Firebase DeepLink не работает при отключенном / завершенном состоянии приложения в iOS14

#ios #deep-linking #firebase-dynamic-links #universal-link

#iOS #глубокая привязка #firebase-dynamic-links #универсальная ссылка

Вопрос:

Я интегрировал Firebase DeepLink/DynamicLinks/UniversalLink его в наше приложение. Когда app is running или background/foreground state включен, Deep Links работает без проблем. Однако, когда приложение находится not running в состоянии или в killed/terminated состоянии, приложение запустится, но метод запуска не будет вызван или инициализирован. Похоже, что это только запускает URL Scheme . Итак, в результате я не могу получить данные о глубоких ссылках, по которым были нажаты, и это было большой проблемой.

In 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
 

Итак, я смог запустить приложение только без сбора данных. Приветствуется любое обходное решение или предложение. Спасибо!

Ответ №1:

Мне потребовалось некоторое время, чтобы решить эту проблему. После нескольких попыток обхода, решение, которое сработало, заключалось в переходе на новое 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.plist , Application 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>