简体   繁体   English

Flutter IOS 通用链接打开应用程序,但没有导航到正确的页面

[英]Flutter IOS Universal Link Opens App, But Does Not Navigate To Correct Page

I have set up Universal Links on my flutter project for IOS.我已经在我的 flutter 项目上为 IOS 设置了通用链接。

Like the title suggests, my app does open when I click on a link relating to my site but it does not navigate to the correct page.正如标题所暗示的那样,当我单击与我的网站相关的链接时,我的应用程序确实会打开,但它不会导航到正确的页面。 It just opens the app.它只是打开应用程序。 I'm not using the uni_links package, rather I used a combination of guides (including official documentation):我没有使用uni_links package,而是使用了指南的组合(包括官方文档):

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

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

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

I have setup my apple-app-site-association file to look like:我已将我的 apple-app-site-association 文件设置为如下所示:

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

and I have added this to my info.plist file:我已将其添加到我的 info.plist 文件中:

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

and my AppDelegate.swift file looks like:我的 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)
  }
}

My Runner-entitlements are also setup correctly like:我的 Runner-entitlements 也已正确设置,例如:

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

The issue is, if I click a hyperlink for www.example.com/mypath , it does not got to the page/route handled by /mypath, but instead just opens the app.问题是,如果我单击www.example.com/mypath的超链接,它不会到达 /mypath 处理的页面/路由,而只是打开应用程序。

My routing is done using go_router : ^5.2.4我的路由是使用go_router完成的:^5.2.4

Please does anyone know why this is happening?请问有人知道为什么会这样吗? I'm blocked by this.我被这个阻止了。 I have seen similar questions, but none with answers that have worked for me.我见过类似的问题,但没有一个答案对我有用。 Any help is appreciated.任何帮助表示赞赏。

Ok so figured it out.好的,所以想通了。 The official apple documentation requests the addition of a variation of this function in the AppDelegate.swift file: Apple 官方文档要求在 AppDelegate.swift 文件中添加此 function 的变体:

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
  }

Seems that it conflicts with the flutter framework for handling universal links.似乎它与处理通用链接的 flutter 框架冲突。 Taking that function out and just having this in my info.plist worked (everything else stayed the same):取出 function 并将其放入我的 info.plist 中(其他一切保持不变):

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

Flutter documentation is not out for this (as at the time of posting this answer) so if people are interested, I could do a small article on the necessary steps. Flutter 文档还没有出来(截至发布此答案时),所以如果人们有兴趣,我可以写一篇关于必要步骤的小文章。

When you handle the dynamic link you get the universal link and other data in the userActivity parameter of the following function.当你处理动态链接时,你会在下面的 function 的 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
}

Parse the data from another function or you can parse in above code also.解析来自另一个 function 的数据,或者您也可以在上面的代码中解析。 In my case I parsed the code in below function.就我而言,我解析了以下 function 中的代码。

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)
    }
}

When you get the details from the link you can simply fetch the navigation controller or the VisibleController, and then can push to the desired flow.当您从链接中获取详细信息时,您可以简单地获取导航 controller 或 VisibleController,然后可以推送到所需的流程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM