swiftuifirebase-dynamic-linksuiscenedelegate

None of SceneDelegate methods (options connectionOptions & continue userActivity) are triggered when opening the app via Firebase Dynamic Link


I'm facing an issue with Firebase Dynamic Links in my iOS application. Whenever I open the app using a dynamic link, none of the functions in my AppDelegate or SceneDelegate seem to be called, except for the indication that the scene went to the background.

Here's my AppDelegate (containing also SceneDelegate)

import Foundation
import KochavaTracker
import UIKit
import AppTrackingTransparency
import RevenueCat
import Firebase
import FirebaseCore
import FirebaseAuth
import FirebaseDynamicLinks
import UserNotifications

class AppDelegate: NSObject, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate {
    let gcmMessageIDKey = "gcm.message_id"
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        
        Purchases.logLevel = .error
        Purchases.configure(
            with: Configuration.Builder(withAPIKey: "@@@@@")
                .with(appUserID: UIDevice.current.identifierForVendor?.uuidString ?? "none")
                .build()
        )
        
        Purchases.shared.delegate = self // set up the delegate
        
        let apparence = UITabBarAppearance() // toolbar fixed
        apparence.configureWithOpaqueBackground()
        if #available(iOS 15.0, *) {UITabBar.appearance().scrollEdgeAppearance = apparence}
        
        incrementAppLaunches()
        
        FirebaseApp.configure()
        
        if checkAndAskForNotifications() {
            Messaging.messaging().delegate = self
            
            if #available(iOS 10.0, *) {
                // For iOS 10 display notification (sent via APNS)
                UNUserNotificationCenter.current().delegate = self
                
                let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
                UNUserNotificationCenter.current().requestAuthorization(
                    options: authOptions,
                    completionHandler: {_, _ in })
            } else {
                let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
                application.registerUserNotificationSettings(settings)
            }
            
            DispatchQueue.main.async {
                application.registerForRemoteNotifications()
            }
        }

        return true
    }
    
    func applicationDidEnterBackground(_ application: UIApplication) {
    }
    
    func incrementAppLaunches() {
        let defaults = UserDefaults()
        let key = "numberOfAppLaunches"
        var count = defaults.integer(forKey: key)
        count += 1
        defaults.set(count, forKey: key)
    }
    
    func checkAndAskForNotifications() -> Bool {
        let defaults = UserDefaults()
        let key = "numberOfAppLaunches"
        let count = defaults.integer(forKey: key)
        
        if count > 2 {
            // Ask for notification permissions
            //print("[checkAndAskForNotifications] count = \(count)")
            return true
        } else {
            //print("[checkAndAskForNotifications] count = \(count)")
            return false
        }
    }
}

class SceneDelegate: NSObject, UISceneDelegate {

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        print("0000")
        // A new scene was added to the app.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIViewController()
            window.makeKeyAndVisible()
        }
    }

    func sceneDidEnterBackground(_ scene: UIScene) {
        print("5555")

        // A scene did enter the background.
    }

    func sceneWillEnterForeground(_ scene: UIScene) {
        print("1111")

        // A scene is about to enter the foreground.
    }


    func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        print("3333")

        guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
            let incomingURL = userActivity.webpageURL,
            let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true),
            let path = components.path else {
                return
        }
        let params = components.queryItems ?? [URLQueryItem]()

        print("path = \(path)")
        print("params = \(params)")
    }
    
}

When I tap on the Firebase Dynamic Link, the app does open, so I know that the scheme is set up correctly. However, nothing is printed in the debug console, except for a message indicating the scene went to the background.

Does anyone know why my SceneDelegate functions aren't being called (except for sceneWillEnterForeground) when using Firebase Dynamic Links? Any help would be greatly appreciated.


Solution

  • I managed to resolve it in an unexpected way. Even though Xcode didn't flag any errors, I found that simply adding FirebaseDynamicLinks to the linked libraries rectified the issue. Once I did that, the app began receiving parameters from Firebase Dynamic Links as expected. It's a bit counterintuitive, but it worked!