You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift配置Firebase单条动态链接 安装后无法获取链接参数

问题场景

当应用未安装时,用户点击动态链接可正常唤起App Store,但完成安装后点击App Store的「打开」按钮启动应用时,虽系统提示「已从浏览器粘贴链接」,但应用启动后动态链接携带的自定义参数丢失,无法正常解析。

已实现配置与代码
  • Universal Link回调方法实现:
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
     let handled = DynamicLinks.dynamicLinks()
       .handleUniversalLink(userActivity.webpageURL!) { dynamiclink, error in
         // ...
           print(dynamiclink!)
           
           let urlStr: String = (dynamiclink?.url?.absoluteString.lowercased())!
           //  UserDefaults.standard.set(urlStr, forKey: "url")
           
           if (urlStr.contains("test?code=azerty")) {
               UserDefaults.standard.set(urlStr, forKey: "url")
               
               let str: String = UserDefaults.standard.value(forKey: "url") as! String
               if (str.contains("test?code=azerty"))
                  {
                   let alert = UIAlertController(title: "test", message: str, preferredStyle: .alert)
                   
                   alert.addAction(UIAlertAction(title: "OK", style:  .default, handler: { action in
                       switch action.style{
                       case .default:
                           print("default")
                       case .cancel:
                           print("cancel")
                       case .destructive:
                           print("destructive")
                       }}))
                   
                   let navigationController = application.windows[0].rootViewController as! UINavigationController
                   let activeViewCont = navigationController.visibleViewController
                   activeViewCont?.view.isUserInteractionEnabled = false
                   //activeViewCont!.present(alertController, animated: true, completion: nil)
                   DispatchQueue.main.asyncAfter(deadline: .now() + 5.0, execute: {
                       activeViewCont!.present(alert, animated: true, completion: nil)
                   })
                  }
           }
       }
     return handled
   }
  • URL Scheme回调方法实现:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
       print(url)
       print("handleOpenURL")
       
       //let urlStr: String = url.absoluteString.replacingOccurrences(of: "colas://", with: "")
       let urlStr: String = url.absoluteString.lowercased()
       //  UserDefaults.standard.set(urlStr, forKey: "url")
       
       if (urlStr.contains("test?code=azerty")) {
           UserDefaults.standard.set(urlStr, forKey: "url")
           
           let str: String = UserDefaults.standard.value(forKey: "url") as! String
           if (str.contains("test?code=azerty"))
              {
               let alert = UIAlertController(title: "test", message: str, preferredStyle: .alert)
               
               alert.addAction(UIAlertAction(title: "OK", style:  .default, handler: { action in
                   switch action.style{
                   case .default:
                       print("default")
                       case .cancel:
                       print("cancel")
                       case .destructive:
                       print("destructive")
                   }}))
               
               let navigationController = app.windows[0].rootViewController as! UINavigationController
               let activeViewCont = navigationController.visibleViewController
               activeViewCont?.view.isUserInteractionEnabled = false
               //activeViewCont!.present(alertController, animated: true, completion: nil)
               DispatchQueue.main.asyncAfter(deadline: .now() + 5.0, execute: {
               activeViewCont!.present(alert, animated: true, completion: nil)
               })
              }
       }
       return true
   }
  • Info.plist配置:
<key>FirebaseDynamicLinksCustomDomains</key>
   <array>
       <string>https://myapp.page.link</string>
   </array>
  • 其他已完成配置:应用内Associated Domains关联域配置、网站apple-app-site-association文件配置、Firebase控制台动态链接配置、自定义URL Scheme配置。
当前回调日志
xxxx.xxxxxxxxx.myapp://google/link/?deep_link_id=https://myapp.page.link/&match_type=unique&utm_medium=dynamic_link&request_ip_version=IP_V4&utm_source=firebase&match_message=Link is uniquely matched for this device.
求助需求

如何在Firebase控制台仅配置单条动态链接的前提下,实现用户从App Store安装应用首次启动时,正常触发动态链接解析回调,获取链接携带的完整参数?

解决方法

问题出在两个核心点,按以下步骤修改即可:

  1. 补全冷启动场景的动态链接监听逻辑
    你现在只实现了App已在前台/后台时的Universal Link、URL Scheme回调,首次安装从App Store点击「打开」属于冷启动场景,不会触发这两个回调,必须在application(_:didFinishLaunchingWithOptions:)里补全Firebase动态链接的初始化和延迟深度链接监听:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // 确保Firebase初始化逻辑在最前面
    FirebaseApp.configure()
    
    // 1. 处理冷启动时通过URL Scheme唤起的链接
    if let launchUrl = launchOptions?[.url] as? URL {
        DynamicLinks.dynamicLinks().handleUniversalLink(launchUrl) { [weak self] dynamicLink, error in
            guard let self = self, error == nil, let targetUrl = dynamicLink?.url else { return }
            self.handleDynamicLink(targetUrl)
        }
    }
    
    // 2. 监听延迟深度链接匹配结果(就是触发系统「已从浏览器粘贴链接」提示的场景)
    DynamicLinks.dynamicLinks().shouldHandleDeepLink { [weak self] dynamicLink, error in
        guard let self = self, error == nil, let targetUrl = dynamicLink?.url else { return }
        self.handleDynamicLink(targetUrl)
    }
    
    return true
}
  1. 抽离统一的链接处理逻辑,去掉重复代码和写死的判断
    你现在两个回调里写了完全重复的参数判断和弹窗逻辑,还强拆可选值容易导致启动崩溃,抽成单独方法统一处理:
func handleDynamicLink(_ url: URL) {
    let fullUrlStr = url.absoluteString.lowercased()
    // 先全量存储链接,调试阶段不要提前加参数过滤,避免漏拿
    UserDefaults.standard.set(fullUrlStr, forKey: "url")
    
    // 拿主窗口的顶层控制器弹窗,不要强制转UINavigationController避免崩溃
    guard let keyWindow = UIApplication.shared.windows.first(where: \.isKeyWindow),
          let rootVC = keyWindow.rootViewController else { return }
    var topVC = rootVC
    while let presented = topVC.presentedViewController {
        topVC = presented
    }
    
    let alert = UIAlertController(title: "动态链接参数获取成功", message: fullUrlStr, preferredStyle: .alert)
    alert.addAction(.init(title: "确定", style: .default))
    // 等页面加载完成再弹窗,不用写死5秒延迟
    DispatchQueue.main.async {
        topVC.present(alert, animated: true)
    }
    
    // 后续再在这里加你的参数解析、页面跳转逻辑
}

改完之后把原来两个回调里重复的参数判断、弹窗代码删掉,拿到dynamicLink的url之后直接调用handleDynamicLink即可。

  1. 修正动态链接参数配置问题
    从你贴的回调日志看,返回的deep_link_id只有域名根路径https://myapp.page.link/,没有你要的test?code=azerty参数,说明你在Firebase控制台创建动态链接时,没有把带参数的完整地址填到「深度链接URL」配置项里,只填了域名根地址。在控制台编辑这条动态链接,把深度链接URL改成你需要的带参数完整地址即可,不需要创建多条链接。

注意:测试首次安装场景时,要先把测试机上的App彻底卸载,点击动态链接跳转到App Store后,不要通过Xcode直接安装覆盖,要模拟真实用户从App Store(TestFlight也可以)点击打开的流程,否则延迟链接匹配不会触发。

内容的提问来源于stack exchange,提问作者ΩlostA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:57:21