Firebase DeepLink 不适用于 iOS14 中的已终止/终止的应用程序状态

问题描述

我已将 Firebase DeepLink/DynamicLinks/UniversalLink 集成到我们的应用中。当 app is runningbackground/foreground state 时,Deep Links 工作没有问题。但是,当应用程序处于 not running 或处于 killed/terminated 状态时,应用程序将启动,但不会调用或初始化任何触发器方法。就好像它只触发 URL Scheme。因此,结果是,我无法获取被点击的深层链接的数据,这是一个大问题。

didFinishLaunchingWithOptions: 中,launchOptions 始终为零,因此 launchOptions[.url] 为零

func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool

并且 open url:options: 不会触发

func application(_ app: UIApplication,open url: URL,options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool

当然这个continue userActivity:restorationHandler:不会触发

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

所以,我只能在没有捕获数据的情况下启动应用程序。任何解决方法或建议表示赞赏。谢谢!

解决方法

我花了一些时间来解决这个问题。在尝试了一系列解决方法后,有效的解决方案是使用 Apple's App Structure 迁移到新的 SceneDelegate

从终止状态处理DeepLink,需要配置这个函数:

var window: UIWindow?

func scene(_ scene: UIScene,willConnectTo session: UISceneSession,options connectionOptions: UIScene.ConnectionOptions) {
    if let userActivity = connectionOptions.userActivities.first,let url = userActivity.webpageURL {            
        DynamicLinks.dynamicLinks().handleUniversalLink(url) { dynamicLink,error in
            guard let dynamicLink = dynamicLink,let url = dynamicLink.url else { return }
            parseDynamicLink(fromURL: url)
        }
    }
    
    guard let windowScene = (scene as? UIWindowScene) else { return }
    
    // Initialize UIWindow
    window = UIWindow(windowScene: windowScene)
    window?.rootViewController = YOUR_ROOT_VIEW_CONTROLLER
    window?.makeKeyAndVisible()
}

处理 UIApplication 等效的场景委托的其他部分:

func scene(_ scene: UIScene,continue userActivity: NSUserActivity) {
    guard let url = userActivity.webpageURL else { return }
    DynamicLinks.dynamicLinks().handleUniversalLink(url) { dynamicLink,error in
        guard let dynamicLink = dynamicLink,let url = dynamicLink.url else { return }
        parseDynamicLink(fromURL: url)
        
        // launch dynamic link code here...?
    }    
}

func scene(_ scene: UIScene,openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let urlContext = URLContexts.first else { return }

    if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: urlContext.url) {
        guard let url = dynamicLink.url else { return }
        parseDynamicLink(fromURL: url)
    }    
}

如果您打算进行迁移,请确保正确配置您的 Info.plistApplication Scene Manifest,然后在此处设置您的场景配置:

func application(_ application: UIApplication,configurationForConnecting connectingSceneSession: UISceneSession,options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    return UISceneConfiguration(name: "Default Configuration",sessionRole: connectingSceneSession.role)
}

您的 Application Scene Manifest 应如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <false/>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneDelegateClassName</key>
                    <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
                    <key>UISceneStoryboardFile</key>
                    <string>Main</string>
                    <key>UISceneConfigurationName</key>
                    <string>Default Configuration</string>
                </dict>
            </array>
        </dict>
    </dict>
</plist>