Swift iOS中的动态链接Web URL查询项为空

问题描述

我从QRCODE扫描中获得了深层链接URL,但它显示Web URL查询为空(已使用Firebase动态链接实现)。关联域设置为“ applinks:avrhub.page.link/Product”。

info.plist中的“ FirebaseDynamicLinksCustomDomains”设置为“ https://avrhub.page.link”和“ https://avrhub.page.link/Product”

enter image description here

深层链接网址:

enter image description here

深层链接代码

func handleIncomingDynamicLink(_ dynamicLink:DynamicLink){
    
    
    
    guard let url = dynamicLink.url else {
            print("My Dynamic Link object has no url")
            return
        }
        print("Your Incoming link Parameter is \(url.absoluteString)")
        
        guard let components = URLComponents(url: url,resolvingAgainstBaseURL: false),let queryItems = components.queryItems else {return}
        for queryItem in queryItems {
            
            Api.Params.inputProductId = Int(queryItem.value!)!
            print("Parameter \(queryItem.name) has a value of \(queryItem.value ?? "")")
        }
        
        Switcher.updateRootVC()
        Api.Params.isDeepLink = true

        if dynamicLink.matchType == .unique {
            print("The dynamic link is Unique")
        }
    }


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
    
}


          
    func application(
        _ app: UIApplication,open url: URL,options: [UIApplication.OpenURLOptionsKey : Any] = [:]
    ) -> Bool {

        ApplicationDelegate.shared.application(
            app,open: url,sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,annotation: options[UIApplication.OpenURLOptionsKey.annotation]
        )
        
        
        
        if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url){
            self.handleIncomingDynamicLink(dynamicLink)
            return true
        } else {
            return GIDSignIn.sharedInstance().handle(url)
        }


    }

即使分析也没有给出任何错误

enter image description here

解决方法

如评论中所述,您不能在firebase控制台中创建具有可变产品ID的动态链接,而需要在旅途中生成它。您还可以根据需要添加其他参数,这些参数可能有助于分析,例如,如果您想知道哪个用户共享链接以及它的影响...

我认为最好在链接中添加产品ID作为查询参数。此外,在多参数的情况下也将有所帮助。您可以使用参数名称轻松解析它,例如:

var productId: String?
let urlComponents = URLComponents(string: urlString)
if let queryItems = urlComponents?.queryItems {
    for queryItem in queryItems {
        if queryItem.name == "product_id" {
           productId = queryItem.value
        }
    }
}

这是我用于以编程方式生成动态链接的代码。

func generateAndShareDynamicLink(event: Event,controller: UIViewController,presentationCompletion: @escaping (() -> Void),dismissCompletion: @escaping (() -> Void) ) {
        
        let user = Utility.shared.getCurrentUser()!
        let ownReferralCode = user.ownReferralCode.value
        let offerShareUrlString = youAPILink + "?referral=" + ownReferralCode + "&event_id=" + event.id.value + "&shared_by=" + user.userId.value + "&shared_by_name=" + user.fullName.value
        
        let url = URL(string: offerShareUrlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!)!
        
        let iOSNavigationParams = DynamicLinkNavigationInfoParameters()
        iOSNavigationParams.isForcedRedirectEnabled = false
        
        let linkComponents = DynamicLinkComponents(link: url,domainURIPrefix: dynamicLinkGenaricDomain)!
        linkComponents.navigationInfoParameters = iOSNavigationParams
        linkComponents.iOSParameters = DynamicLinkIOSParameters(bundleID: bundleId)
        linkComponents.iOSParameters?.appStoreID = kAppStoreId
        linkComponents.iOSParameters?.customScheme = theBarCodeInviteScheme
        
        linkComponents.androidParameters = DynamicLinkAndroidParameters(packageName: androidPackageName)
        
        let descText = "\(user.fullName.value) has shared an event with you,check it out!"
        linkComponents.socialMetaTagParameters = DynamicLinkSocialMetaTagParameters()
        linkComponents.socialMetaTagParameters?.title = "App Name"
        linkComponents.socialMetaTagParameters?.descriptionText = descText
        linkComponents.socialMetaTagParameters?.imageURL = tbcLogoUrl
        
        linkComponents.otherPlatformParameters = DynamicLinkOtherPlatformParameters()
        linkComponents.otherPlatformParameters?.fallbackUrl = URL(string: barCodeDomainURLString)
        
        linkComponents.shorten { (shortUrl,warnings,error) in
            
            guard error == nil else {
                presentationCompletion()
                controller.showAlertController(title: "Share Event",msg: error!.localizedDescription)
                return
            }
            
            if let warnings = warnings {
                debugPrint("Dynamic link generation warnings: \(String(describing: warnings))")
            }
            
            let activityViewController = UIActivityViewController(activityItems: [descText,shortUrl!],applicationActivities: nil)
            activityViewController.popoverPresentationController?.sourceView = controller.view
            activityViewController.completionWithItemsHandler = { (activityType,completed:Bool,returnedItems:[Any]?,error: Error?) in
                dismissCompletion()
            }
            controller.present(activityViewController,animated: true,completion: {
                presentationCompletion()
            })
        }
        
    }
,

我同意另一个答案,即解决此问题的最佳方法是让后端开发人员使用Firebase动态链接SDK正确生成动态链接并嵌入QR代码。

但是,如果您没有控制权,则可以获取传入链接并将其解析为嵌入的产品ID。在这种情况下,您不需要使用某些动态链接功能,而可以执行以下操作:

if let incomingURL = userActivity.webpageURL {
    print("incoming URL is \(incomingURL)")
    handleIncomingURL(incomingURL)
}

//快速而肮脏的解析-您可以根据自己的情况做一些更强大的操作

func handleIncomingURL(_ url:URL) {
    
    guard let components = URLComponents(url: url,resolvingAgainstBaseURL: true),let host = components.host else {
        return
    }
    var pathComponents = components.path.components(separatedBy: "/")
    // the first component is empty
    pathComponents.removeFirst()
    
    if pathComponents[0] == "Product" && pathComponents[1] != nil {
        print("found productId: \(pathComponents[1])")
        //Action here: jump to the right page from here,now that you have a product ID to work with
    } else {
        print("invalid URL path for my use case....")
    }
}
,

我遇到了同样的问题,因为我在尝试从下面的函数获取 Firebase 动态链接时总是得到 nil

DynamicLinks.dynamicLinks().dynamicLink(:)

我在 Github 上发现了一个有用的帖子,说明我们需要在动态链接中使用的 .plist 文件中添加域。

这对我有用,可能会对某人有所帮助。

您可以在 plist 中添加您的域,如下所示:

<key>FirebaseDynamicLinksCustomDomains</key>
    <array>
        <string><YOUR_DOMAIN_NAME></string>
    </array>

确保您在域名中指定 https:// 或 http://。

注意:如果您想探索如何处理 iOS 13 和更高版本 iOS 的 Firebase 动态链接。 You can visit this answer.