2

We are using Branch to implement deep linking in our iOS app. Now if I run the application, and then try to open it through the link by branch, the branch.initSession gets called and I can access the deep link data. However, if I try to open the branch link directly when the app is not launched, the andRegisterDeepLinkHandler callback from branch.initSession does not get executed - this basically nullifies the point of deep linking.

Our AppDelegate code:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let branch: Branch = Branch.getInstance()
    branch.initSession(launchOptions: launchOptions, andRegisterDeepLinkHandler: {params, error in

        DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {

            let alert = UIAlertController(title: "Branch", message: "\(params as? [String: AnyObject])", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
            self.window?.rootViewController?.present(alert, animated: false, completion: nil)
        })

        if error == nil {
            // params are the deep linked params associated with the link that the user clicked -> was re-directed to this app
            // params will be empty if no data found
            // TODO: ... insert custom logic here ...
            print("params: %@", params as? [String: AnyObject] ?? {})
        }
    })
    ...
    // facebook SDK login integration
    return SDKApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
}

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
    // pass the url to the handle deep link call
    let branchHandled = Branch.getInstance().application(application,
                                                         open: url,
                                                         sourceApplication: sourceApplication,
                                                         annotation: annotation)
    return branchHandled
}

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    // pass the url to the handle deep link call
    let branchHandled = Branch.getInstance().application(app,
                                                         open: url,
                                                         options: options)
    return branchHandled
}
Milan Nosáľ
  • 19,169
  • 4
  • 55
  • 90

1 Answers1

4

We've been able to fix this the following way. The problem is the return value of the application(_:,didFinishLaunchingWithOptions:) in our AppDelegate. We have been delegating generation of the return value to the SDKApplicationDelegate.shared by facebook. Seems that branch.initSession requires the application(_:,didFinishLaunchingWithOptions:) to return true, while SDKApplicationDelegate.shared in those cases mentioned in question returned false.

This is documented, but it is pretty hard to get to it in the documentation, especially if you are no aware that the issue is caused by using branch and facebook SDK together.

documentation screenshot

Therefore the fix was in updating the application(_:,didFinishLaunchingWithOptions:) implementation:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let branch: Branch = Branch.getInstance()
    branch.initSession(launchOptions: launchOptions, andRegisterDeepLinkHandler: {params, error in
        if error == nil {
        // params are the deep linked params associated with the link that the user clicked -> was re-directed to this app
        // params will be empty if no data found
        // TODO: ... insert custom logic here ...
        print("params: %@", params as? [String: AnyObject] ?? {})
        }
        })
    ...

    // facebook SDK login integration
    SDKApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)

    // always return true!
    return true
}

It all originated by me following answers from this question when integration Facebook. I have added an answer with a fix there too, so there's a chance that other won't fall for it too.

Hopefully this will save someone few hours.

Milan Nosáľ
  • 19,169
  • 4
  • 55
  • 90