Reputation: 3280
I have integrated the Firebase DeepLink/DynamicLinks/UniversalLink
into our app. When the app is running
or in background/foreground state
, Deep Links
works with no problem. However, when the app is not running
or in killed/terminated
state the app will launch, but no trigger method will be called or initialize. It's like it only triggers the URL Scheme
. So, as a result, I am not able to get the data on the deep links that were clicked, and that was the big problem.
In didFinishLaunchingWithOptions:
launchOptions
is always nil, and therefore launchOptions[.url]
is nil
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
And open url:options:
does not trigger
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool
And ofcourse this one continue userActivity:restorationHandler:
does not trigger
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
So, I was only able to launch the app with no data captured. Any workaround or suggestion is appreciated. Thanks!
Upvotes: 1
Views: 2627
Reputation: 3280
Took me sometime to resolve this issue. After trying a bunch of workaround, the solution that worked was to migrate to the new Apple's App Structure
using SceneDelegate
.
To handle DeepLink from terminated state, you need to configure this function:
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()
}
To handle the other part of the scene delegate which are UIApplication equivalent:
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)
}
}
If you plan to do the migration, make sure to properly configure your Info.plist
's Application Scene Manifest
then set your scene configuration here:
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
Your Application Scene Manifest
should look something like this:
<?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>
Upvotes: 6