【问题标题】:Dynamic Links Firebase function not being called at all Xcode 12?动态链接 Firebase 函数根本没有被 Xcode 12 调用?
【发布时间】:2021-01-01 17:52:07
【问题描述】:

所以我有一个正在运行的动态链接,当我点击它时它会打开应用程序,但动态链接的处理不会发生。这是因为从未输入过下面看到的应用程序功能,我不知道为什么......

func handleIncomingDynamicLink(_ dynamicLink: DynamicLink){
    guard let url = dynamicLink.url else {
        print("That's weird. My dynamic link object has no url")
        return
    }
    print("Your incoming link parameter is \(url.absoluteString)")
}

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    if let incomingURL = userActivity.webpageURL {
        print("Incoming URL is \(incomingURL)")
        let linkHandled = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { (dynamicLink, error) in
            guard error == nil else{
                print("Found an error! \(error!.localizedDescription)")
                return
            }
            if let dynamicLink = dynamicLink {
                self.handleIncomingDynamicLink(dynamicLink)
            }
        }
        if linkHandled {
            return true
        } else {
            return false
        }
    }
    return false
}

任何帮助将不胜感激——这可能是 Firebase 本身的问题吗?

【问题讨论】:

  • 你使用 Xcode 12/SwiftUI 2.0 吗?
  • @Asperi 是的,我们正在使用它

标签: swift xcode firebase swiftui firebase-dynamic-links


【解决方案1】:

SwiftUI 2.0 / @main 应用 对于新的 SwiftUI 2.0,您可以仅使用 SwiftUI 制作应用程序。这意味着您不使用 AppDelegate 或 SceneDelegate。然后,您必须使用 .onOpenURL 来获取单击链接时调用的任何操作。我将它用于 Firebase 动态链接。

WindowGroup {
  ContentView()
    .onOpenURL { url in
      // handle the URL that must be opened
      let incomingURL = url
      print("Incoming URL is: \(incomingURL)")
      let linkHandled = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { (dynamicLink, error) in
          guard error == nil else {
             print("Error found!: \(error!.localizedDescription)")
                return
          }
          if let dynamicLink = dynamicLink {
             self.handleDynamicLink(dynamicLink)
          }
       }
       if linkHandled{
          print("Link Handled")
          return
       }else{
          print("NO linkHandled")
          return
       }
    }
}

【讨论】:

    【解决方案2】:

    在 iOS 上配置 Firebase 动态链接有几个必须遵循的步骤。所以,我推荐参考官方文档here。此外,还有一个 Firecasts 系列介绍了所有步骤 here

    我关注的是 Firecasts 系列,但我的设置略有不同;所以,我遇到了几个问题。首先,我使用的是自定义域。其次,我正在使用 SwiftUI。我将仅解决我遇到的问题,因此请参阅完整的 Firecasts 系列以了解所有令人毛骨悚然的细节。

    SwiftUI 2.0

    您的应用需要处理两种不同类型的链接。首先,您的应用需要在您的应用已安装时处理链接(即https://app.yourcustomdomain.com/...)。其次,您的应用需要在安装应用之前处理复制到剪贴板的链接(即com.your.bundle.id://google/link/...)。

    此外,您可能希望处理源自网络浏览器 (Safari) 的链接。就我而言,我处理来自 QR 码扫描的链接。显然 NFC 标签扫描链接也来自 Safari,但我无法确认。

    经过反复试验,我找到了一种使用 SwiftUI 处理所有这些问题的方法;尚不清楚这是否是官方推荐的方法,因此请谨慎行事。

    首先,使用onOpenURL(perform:).onContinueUserActivity(_,perform:)

    var body: some Scene {
        WindowGroup {
            ContentView()
                .onContinueUserActivity(NSUserActivityTypeBrowsingWeb, perform: onWebBrowserActivity)
                .onOpenURL(perform: onOpenURL)
        }
    }
    

    其次,定义onContinueUserActivity处理程序:

    // Handles links originating from the web browser
    func onWebBrowserActivity(_ userActivity: NSUserActivity) {
        guard let url = userActivity.webpageURL else {
            return
        }
        onOpenURL(url)
    }
    

    三、定义onOpenURL处理程序:

    func onOpenURL(_ url: URL) {
        let dynamicLinks = DynamicLinks.dynamicLinks()
        if dynamicLinks.shouldHandleDynamicLink(fromCustomSchemeURL: url),
           let dynamicLink = dynamicLinks.dynamicLink(fromCustomSchemeURL: url) {
            handle(dynamicLink: dynamicLink)
        } else {
            handleUniversalLink(url: url)
        }
    }
    

    上面提到的两种类型的链接都被传递到 onOpenURL 处理程序中,所以这个 if 语句处理了这两种情况。

    最后,(正如其他人提到的)处理通用链接:

    func handleUniversalLink(url: URL) {
        let linkHandled = DynamicLinks.dynamicLinks().handleUniversalLink(url) { dynamicLink, error in
            if let error = error {
                print("Could not follow the dynamic link \(error.localizedDescription)")
                return
            }
            if let dynamicLink = dynamicLink {
                self.handle(dynamicLink: dynamicLink)
            }
        }
        if linkHandled {
            print("Link handled")
        } else {
            print("Link not handled")
        }
    }
    

    自定义域

    我必须遵循自定义域设置说明here。具体来说,我必须设置 Firebase 托管,这需要添加 A DNS 记录(除了为动态链接 URL 前缀设置设置 TXT DNS 记录)。另外,我必须在 Info.plist 中指定自定义域

       <key>FirebaseDynamicLinksCustomDomains</key>
       <array>
               <string>https://app.yourcustomdomain.com</string>
       </array>
    

    【讨论】:

      【解决方案3】:

      SwiftUI 1.0 / SceneDelegate

      您也可以这样做,但在您的 SceneDelegate 中,遵循回调:

      func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
          if let incomingURL = userActivity.webpageURL {
              print("Incoming URL is \(incomingURL)")
              let linkHandled = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { (dynamicLink, error) in
                  guard error == nil else{
                      print("Found an error! \(error!.localizedDescription)")
                      return
                  }
                  if let dynamicLink = dynamicLink {
                      self.handleIncomingDynamicLink(dynamicLink)
                  }
              }
      }
      

      SwiftUI 2.0 / WindowGroup

      使用 SwiftUI 2.0 生命周期,您需要改用 .onContinueUserActivity,例如

      WindowGroup {
          ContentView()
           .onContinueUserActivity(<your_activity_type_here>) { userActivity in
               if let incomingURL = userActivity.webpageURL {
                    print("Incoming URL is \(incomingURL)")
                    let linkHandled = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { (dynamicLink, error) in
                          guard error == nil else{
                               print("Found an error! \(error!.localizedDescription)")
                               return
                          }
                          if let dynamicLink = dynamicLink {
                               self.handleIncomingDynamicLink(dynamicLink)
                          }
                    }
              }
          }
      }
      

      【讨论】:

      • 什么类型的参数应该替换 我不太确定
      • @Asperi 我和 TJ 有同样的问题——我应该在参数列表中添加什么?
      • 它是字符串,您在 Info.plist 中声明为支持的任何受支持的 NSUserActivityTypes。 developer.apple.com/documentation/foundation/task_management/…
      • @Asperi 我已经这样做了,但代码仍然永远不会运行!这段代码应该放在场景中的什么地方以及如何放置
      • 在 SwiftUI 2.0 生命周期中没有 SceneDelegate。你使用 UIKit 生命周期吗?您是通过 WindowGroup 还是 SceneDelegate 创建窗口?
      猜你喜欢
      • 2016-11-20
      • 1970-01-01
      • 2020-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多