2

I followed all the steps from Firebase Dynamic Links documentation.

The Associated Domains is active and domain is already added also I add URL Schemes inside the info tab and programmatically inside the launchOptions function.

Deep link is opening the app but the only method triggered after clicking on dynamic link is willContinueUserActivityWithType which returning nil userActivity

In documentation mentioned continueUserActivity have to trigger if app is running on background but in my case not happening and I could find any other way to reed deep link data.

Here is my AppDelegate code:

import UIKit
import Firebase

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {    

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let options = FirebaseOptions(contentsOfFile: filePath)
        options?.deepLinkURLScheme = "com.example"
        FirebaseApp.configure(options: options!)        
        .
        .
        .

    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
        print("applicationDidBecomeActive")
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }

    func application(_ application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool {

        if let incomigURL = userActivity?.webpageURL{
            let linkHandle = DynamicLinks.dynamicLinks().handleUniversalLink(incomigURL) { (dynamiclink, error) in
                if let dynamiclink = dynamiclink, let _ = dynamiclink.url {
                    self.handleIncomingDynamicLink(dynamicLink: dynamiclink)
                } else {
                    print("willContinueUserActivityWithType | dynamiclink = nil")
                }
            }
            return linkHandle
        }
        print("willContinueUserActivityWithType |  userActivity = nil")
        return false
    }

    func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
        if let incomigURL = userActivity.webpageURL{
            let linkHandle = DynamicLinks.dynamicLinks().handleUniversalLink(incomigURL) { (dynamiclink, error) in
                if let dynamiclink = dynamiclink, let _ = dynamiclink.url {
                    self.handleIncomingDynamicLink(dynamicLink: dynamiclink)
                } else {
                    print("continueUserActivity |  dynamiclink = nil")
                }
            }
            return linkHandle
        }
        print("continueUserActivity = nil")
        return false
    }

    @available(iOS 9.0, *)
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
        return application(app, open: url,
                           sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
                           annotation: "")
    }

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        print("Handle deep link.")
        return true
    }

    func handleIncomingDynamicLink(dynamicLink: DynamicLink){
        print("Your dynamic link parameter is = \(String(describing: dynamicLink.url))")
    }

}
Soheil
  • 325
  • 4
  • 19

2 Answers2

3

In swift 4.2 change the instant method to:

  func application(_ application: UIApplication, 
                     continue userActivity: NSUserActivity, 
           restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool

So for handling Firebase deep link NSUserActivity function have to be like this:

func application(_ application: UIApplication,
                              continue userActivity: NSUserActivity,
                              restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        if let incomigURL = userActivity.webpageURL{
            let linkHandle = DynamicLinks.dynamicLinks().handleUniversalLink(incomigURL) { (dynamiclink, error) in
                if let dynamiclink = dynamiclink, let _ = dynamiclink.url {
                    self.handleIncomingDynamicLink(dynamicLink: dynamiclink)
                } else {
                    print("dynamiclink = nil")
                }
            }
            return linkHandle
        }
        print("userActivity = nil")
        return false
    }

Special thanks to user1376400

Soheil
  • 325
  • 4
  • 19
0

Are you using the same team ID profile you mentioned in app association file {"appID":"TeamID","paths":["/*"]}]} in your application.

Check your domain name match with Associated Domains applink.

Validate your apple-app-site-association using some validator https://branch.io/resources/aasa-validator/

user1376400
  • 614
  • 1
  • 4
  • 8
  • Yes I just checked the domain is valid and the team ID is same as the one I'm using for the debug mode of my app, have to mention I also added same team id in Firebase console. This is how my path looks like: {"appID":"TeamID.bundleID","paths":["/*"]}]} – Soheil Oct 18 '18 at 15:08
  • Donot use team id in your Firebase console. Find your team id from your profile you used to run app. https://developer.apple.com/account/#/membership . Try to press the link long time. Is it showing open app. Once you open in web its always open in web it self – user1376400 Oct 18 '18 at 15:12
  • Yes I get the ID from here and set it in Firebase console. – Soheil Oct 18 '18 at 15:14
  • can you share your URL. I can check here – user1376400 Oct 18 '18 at 15:15
  • https://mistertyretest.page.link/test/apple-app-site-association file missing . Where is apple-app-site-association file? can you share the url of apple-app-site-association – user1376400 Oct 18 '18 at 15:21
  • can you try with "paths": ["*"] – user1376400 Oct 18 '18 at 15:28
  • the path is generated by Firebase, how can I change it? – Soheil Oct 18 '18 at 15:29
  • your app link : mistertyretest.page.link Is that right? – user1376400 Oct 18 '18 at 15:35
  • Yes I just checked again. – Soheil Oct 18 '18 at 15:36
  • try to long press the link mistertyretest.page.link.. remove /test – user1376400 Oct 18 '18 at 15:41
  • when I past the link in note app and then long press it is showing open app. – Soheil Oct 18 '18 at 15:43
  • It is working and it is opening the app but the continueUserActivity is not triggering and I cannot get the email link inside AppDelegate. – Soheil Oct 18 '18 at 15:57
  • put AnyObject instead of Any func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool { Change AnyObject to Any Hope this work – user1376400 Oct 18 '18 at 16:02
  • Put Any in NSUserActivity delegate instead of AnyObject – user1376400 Oct 18 '18 at 16:05
  • No luck its not working I tried both func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([Any]?) -> Void) -> Bool { and func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([NSUserActivity]?) -> Void) -> Bool { – Soheil Oct 18 '18 at 16:09
  • 1
    Check this method changed in Swift 4.2 https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623072-application . I think you copied from example. Write a fresh method and keep simple – user1376400 Oct 18 '18 at 16:15
  • OMG, just this thing `UIUserActivityRestoring` mess with me entire day. its working now, Thank you so much for your help and time – Soheil Oct 18 '18 at 16:19
  • Great.. Good Job – user1376400 Oct 18 '18 at 16:20