Firebase Deeplink未调用应用程序:continueUserActivity:Swift 3中AppDelegate的restorationHandler函数

时间:2017-09-29 03:46:18

标签: ios swift firebase deep-linking firebase-dynamic-links

我正在使用firebase Deeplink URL打开我应用的特定部分。当应用程序在后台运行时它运行良好,但当我杀死应用程序并从外部点击deeplink url时,我不知道如何处理这种情况,我的意思是我应该写出我的条件来获取url的参数。

app appate的这种方法在后台app时被调用

   @available(iOS 8.0, *)
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
    guard let dynamicLinks = DynamicLinks.dynamicLinks() else {
        return false
    }
    let handled = dynamicLinks.handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
        if let dynamicLink = dynamiclink, let _ = dynamicLink.url
        {
            var path = dynamiclink?.url?.path
            path?.remove(at: (path?.startIndex)!)
            let delimiter = "/"
            var fullNameArr = path?.components(separatedBy: delimiter)
            let type: String = fullNameArr![0]
            let Id: String? = (fullNameArr?.count)! > 1 ? fullNameArr?[1] : nil
            if(type == "games")
            {
                self.callGameDetailView(gameId: Id! , gameType: "created", notificationId: "NIL" )

            }else{
                var paths = dynamicLink.url?.path
                paths?.remove(at: (path?.startIndex)!)
                self.setRewardViewController(paths!)

            }
        } else {
            // Check for errors
        }
    }
    return handled
}

但是当我杀死应用并点击动态链接网址时,它不会调用open url方法:

@available(iOS 9.0, *)
func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any])
    -> Bool {

   return self.application(application, open: url, sourceApplication: nil, annotation: [:])


}


func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {

    let dynamicLink = DynamicLinks.dynamicLinks()?.dynamicLink(fromCustomSchemeURL: url)
    if let dynamicLink = dynamicLink
    {
        var path = dynamicLink.url?.path
        path?.remove(at: (path?.startIndex)!)
        let delimiter = "/"
        var fullNameArr = path?.components(separatedBy: delimiter)
        let type: String = fullNameArr![0]
        let Id: String? = (fullNameArr?.count)! > 1 ? fullNameArr?[1] : nil
        if(type == "games")
        {
            self.callGameDetailView(gameId: Id! , gameType: "created", notificationId: "NIL" )

        }else{
            var paths = dynamicLink.url?.path
            paths?.remove(at: (path?.startIndex)!)
            self.setRewardViewController(paths!)
            return true
        }
    }

    return FBSDKApplicationDelegate.sharedInstance().application(
        application,
        open: url,
        sourceApplication: sourceApplication,
        annotation: annotation)
}

简而言之,我不知道如何在app第一次运行时处理动态链接或在杀死应用程序后运行?

4 个答案:

答案 0 :(得分:3)

我也有同样的问题,你需要从launchOptions

获得NSUserActivity
var launchURL :URL? = nil

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            ....
            // this code should have worked but not working for me with Xcode 9
            //        if let userActivityDictionary = launchOptions?[.userActivityDictionary] as? [UIApplicationLaunchOptionsKey : Any],
            //            let auserActivity = userActivityDictionary[.userActivityType] as? NSUserActivity {
            //            launchURL = auserActivity.webpageURL
            //        }

             if let userActDic = launchOptions?[UIApplicationLaunchOptionsKey.userActivityDictionary] as? [String: Any],
                        let  auserActivity  = userActDic["UIApplicationLaunchOptionsUserActivityKey"] as? NSUserActivity{

                        NSLog("type \(userActDic.self),\(userActDic)") // using NSLog for logging as print did not log to my 'Device and Simulator' logs
                        launchURL = auserActivity.webpageURL
                    }
            ...
            }

func applicationDidBecomeActive(_ application: UIApplication) {
            if let url = self.launchURL {
                self.launchURL = nil

                DispatchQueue.main.asyncAfter(deadline: .now()+2.0, execute: {
                    // wait to initalize notifications

                    if let dynamicLinks = DynamicLinks.dynamicLinks()  {
                        NSLog("handling \(dynamicLinks)")
                        dynamicLinks.handleUniversalLink(url) { (dynamiclink, error) in
                            if let link = dynamiclink?.url {
                                NSLog("proceessing \(dynamicLinks)")
                                let strongMatch = dynamiclink?.matchConfidence == .strong
    // process dynamic link here
                                self.processDynamicLink(withUrl: link, andStrongMatch: strongMatch)
                            }
                        }

                    }

                })
            }

        }

答案 1 :(得分:0)

当使用URI方案打开应用程序时,将调用您引用的两个openURL AppDelegate方法。 URI方案功能仅适用于非常特定的场景。在iOS 9中,Apple切换到Universal Links,它实际上调用函数application:continueUserActivity:restorationHandler:

此功能不会调用openURL方法,因此您必须在首先提到的continueUserActivity中完成所有通用链接处理。

为了在处理其他边缘资源时节省很多麻烦,我建议转移到另一个第三方提供商,如Branch(完全披露,我在那里工作),因为他们将所有这些处理捆绑到一个回调并提供Firebase用户无法使用的更多功能和归因相关服务。

答案 2 :(得分:0)

在application:didFinishLaunchingWithOptions:方法中,您需要注册customURLScheme。

FirebaseOptions.defaultOptions()?.deepLinkURLScheme = YOUR_URL_SCHEME

答案 3 :(得分:0)

我也整天都面临着同样的问题。 Firebase SDK无法处理这种极端情况,并且在其文档的任何地方均未提及。非常令人沮丧!

在针对iOS 13和更高版本的操作系统进行调查之后找到了解决方案。 Firebase Dynamic链接有效,并且即使应用程序首次运行或在杀死应用程序后也可以重定向到特定页面。

在SceneDelegate中而不是AppDelegate中包含以下代码

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 

if let firstUrlContext = connectionOptions.userActivities.first,let url = firstUrlContext.webpageURL  {
                    DynamicLinks.dynamicLinks().handleUniversalLink(url) { (dynamiclink, error) in
                      if let dynamiclink = dynamiclink {
                        self.handleDynamicLink(dynamiclink)
                      }
                    }
                    
                }
}