Универсальная ссылка Flutter IOS открывает приложение, но не переходит на правильную страницу

Я настроил Universal Links в своем проекте флаттера для IOS.

Как следует из названия, мое приложение открывается, когда я нажимаю на ссылку, относящуюся к моему сайту, но не переходит на нужную страницу. Он просто открывает приложение. Я не использую пакет uni_links, а использовал комбинацию руководств (включая официальную документацию):

https://developer.apple.com/videos/play/wwdc2019/717/

https://nishbhasin.medium.com/apple-universal-link-setup-in-ios-131a508b45d1

https://www.kodeco.com/6080-universal-links-make-the-connection

Я настроил свой файл ассоциации Apple-App-Site-Association, чтобы он выглядел так:

{
    "applinks": {
        "details": [
            {
                "appIDs": [
                    "XXXXXXX.com.my.appBundle"
                ],
                "componenents": [
                    {
                        "/": "/*"
                    }
                ]
            }
        ]
    }
}

и я добавил это в свой файл info.plist:

<key>FlutterDeepLinkingEnabled</key>
<true/>

и мой файл AppDelegate.swift выглядит так:

import UIKit
import Flutter
import Firebase

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(_ application: UIApplication, continue userActivity: NSUserActivity, 
    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    // This will allow us to check if we are coming from a universal link
    // and get the url with its components
    // The activity type (NSUserActivityTypeBrowsingWeb) is used
    // when continuing from a web browsing session to either
    // a web browser or a native app. Only activities of this
    // type can be continued from a web browser to a native app.
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
      let url = userActivity.webpageURL,
      let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
        return false
    }
    // Now that we have the url and its components,
    // we can use this information to present
    // appropriate content in the app
    return true
  }

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FirebaseApp.configure()
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

Мои права Runner также настроены правильно, например:

<key>com.apple.developer.associated-domains</key>
<array>
    <string>applinks:www.example.com</string>
    <string>applinks:*.example.com</string>
</array>

Проблема в том, что если я щелкну гиперссылку для www.example.com/mypath, она не попадет на страницу/маршрут, обрабатываемый /mypath, а просто откроет приложение.

Моя маршрутизация выполняется с помощью go_router: ^5.2.4

Пожалуйста, кто-нибудь знает, почему это происходит? Я заблокирован этим. Я видел похожие вопросы, но ни один из ответов не сработал для меня. Любая помощь приветствуется.

Вы получаете компоненты, включенные в ссылки?

Mayank Verma 25.01.2023 07:13

@MayankVerma не совсем уверен, что вы имеете в виду, но я также попытался добавить компонент, который жестко запрограммировал путь в моем приложении, все равно получил те же результаты. В основном "/": "/feed" как компонент, но когда я щелкнул www.example/feed, тот же результат... он просто открыл приложение.

Kosy Onyenso 25.01.2023 07:31
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
68
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Когда вы обрабатываете динамическую ссылку, вы получаете универсальную ссылку и другие данные в параметре userActivity следующей функции.

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    if let incomingURL = userActivity.webpageURL {
        debugPrint("incoming url is", incomingURL)
        let link = DynamicLinks.dynamicLinks().shouldHandleDynamicLink(fromCustomSchemeURL: incomingURL)
        print(link)
        let linkHandle = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { link, error in
            guard error == nil else {
                print("Error found.")
                return
            }
            if let dynamicLink = link {
                self.handleDynamicLinks(dynamicLink)
            }
        }
        if linkHandle {
            return true
        } else {
            return false
        }
    }
    return false
}

Проанализируйте данные из другой функции или вы также можете проанализировать приведенный выше код. В моем случае я проанализировал код в функции ниже.

func handleDynamicLinks(_ dynamicLink: DynamicLink) {
    guard let link = dynamicLink.url else {
        return
    }
    
    if let landingVC = self.window?.rootViewController as? LandingViewController {
       // Do you your handling here with any controller you want to send or anything.
    }
          // example you are getting ID, you can parse it here

    if let idString = link.valueOf("id"), let id = Int.init(idString) {
        print(id)
    }
}

Когда вы получите подробную информацию по ссылке, вы можете просто получить навигационный контроллер или VisibleController, а затем перейти к нужному потоку.

Я вижу, что вы пытаетесь сделать. Проблема в том, что я использую стороннюю библиотеку маршрутизации с флаттером, и функция handledynamiclinks() может вызвать конфликты. Мой вопрос чрезвычайно специфичен для флаттера. Спасибо за помощь.

Kosy Onyenso 25.01.2023 18:21

Без вопросов. Желаем удачи @KosyOnyenso

Mayank Verma 27.01.2023 08:19
Ответ принят как подходящий

Ок так разобрался. Официальная документация Apple требует добавления варианта этой функции в файл AppDelegate.swift:

func application(_ application: UIApplication, continue userActivity: NSUserActivity, 
    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    // This will allow us to check if we are coming from a universal link
    // and get the url with its components
    // The activity type (NSUserActivityTypeBrowsingWeb) is used
    // when continuing from a web browsing session to either
    // a web browser or a native app. Only activities of this
    // type can be continued from a web browser to a native app.
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
      let url = userActivity.webpageURL,
      let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
        return false
    }
    // Now that we have the url and its components,
    // we can use this information to present
    // appropriate content in the app
    return true
  }

Кажется, что это конфликтует с флаттер-фреймворком для обработки универсальных ссылок. Убрать эту функцию и просто иметь это в моем info.plist сработало (все остальное осталось прежним):

<key>FlutterDeepLinkingEnabled</key>
<true/>

Документация по Flutter для этого отсутствует (на момент публикации этого ответа), поэтому, если люди заинтересованы, я мог бы написать небольшую статью о необходимых шагах.

Другие вопросы по теме