Firebase Deeplink not calling application:continueUserActivity:restorationHandler function of AppDelegate in Swift 3
Asked Answered
G

4

6

I am using firebase Deeplink URL to open my app's specific section. It is working well when app running in background but when I killed the app and click deeplink url from outside than I don't know how to handle that case, I mean where I should write my condition to get the parameters of url.

This method of app delegate called when app in background

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

but it will not call open url method when I killed the app and hit the dynamic link 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)
}

In short I have no Idea how to handle the dynamic link when app runs first time or run after killing the app?

Gillman answered 29/9, 2017 at 3:46 Comment(1)
Metod "func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool" is be called when your iOS App is installed and you tapping on dynamic link. Please, re-check this. Firebase Dynamic Links are using iOS Universal Links when App is already installed, so you can re-check are your Universal Links configured properly. For additional debugging, run DynamicLinks.performDiagnostics(completion: nil) and post output here.Antepast
C
5

I also have same issue, you need to get NSUserActivity from launchOptions

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

                    }

                })
            }

        }
Cloudscape answered 13/10, 2017 at 4:56 Comment(2)
Thank you! I was fighting this issue all day. Shame that Firebase SDK does not handle this edge case, even five months later... One question though, why the two seconds delay before handling dynamic links?Gianina
to make sure app is loaded completely.. can change or remove the delayCloudscape
R
2

I also facing this same issue all day. Firebase SDK does not handle this edge case and didn't mention anywhere in their documentation. Very frustrating!

Found a solution after the investigation for iOS 13 and later OS. Firebase Dynamic link is working and also able to redirect to a specific page even when the app runs the first time or run after killing the app.

Have the below code in the SceneDelegate instead of 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)
        }
      }
    }
  }
Rump answered 6/12, 2020 at 17:18 Comment(1)
I love you so much.Equestrian
F
0

The two openURL AppDelegate methods that you are referencing are called when the application is opened by use of a URI scheme. URI scheme functionality will only work in very specific scenarios. In iOS 9, Apple switched to Universal Links, which actually call the function application:continueUserActivity:restorationHandler:.

This function does not call the openURL methods so all of your Universal links handling will have to be done in the continueUserActivity that you mentioned first.

For the sake of saving yourself a lot of trouble in handling other edgecases, I'd suggest moving to another 3rd party provider like Branch (Full disclosure, I work there) since they bundle all of this handling into one callback and provide more functionality and attribution related services that are not available to Firebase users.

Fled answered 29/9, 2017 at 18:3 Comment(1)
Thanks @clayjones94, but my problem is that my firebase deeplink is working fine i,e take user to specific content when app is running background but when I killed the app than deep link open the App but does not bring user to specific content in the app. What I am missing in my code?Gillman
I
0

In application:didFinishLaunchingWithOptions: method, you need to register your customURLScheme.

FirebaseOptions.defaultOptions()?.deepLinkURLScheme = YOUR_URL_SCHEME
Improbable answered 9/10, 2017 at 17:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.