Search code examples
iosuikitios-universal-linksuiscenedelegate

Issues with IOS Universal link launch


I have followed this documentation to set up Universal links. I think I've set up everything successfully because when I tap a universal link, my app is launching and I'm receiving the URL in scene(_:willConnectTo:options:), as shown below:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
    Log("SceneDelegate.scene(_:willConnectTo:options:)")
        
    let userActivities: Set<NSUserActivity> = connectionOptions.userActivities
        
    for userActivity in userActivities {
            
        guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
            let universalLink = userActivity.webpageURL else {
            Log("Not launched via universal links!")
            return
        }
            
        Log(String(format: "userActivities = %@", String(describing: userActivity)))
        Log(String(format: "universalLink = %@", universalLink.absoluteString))

        // Update UI
    }
}

But when my app is running in background and a universal link is used, my app comes to the foreground, but link is not delivered as a NSUserActivity object to scene(_:continue:) as documented.

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        
        Log("SceneDelegate.scene(_:continue:)")
        
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
        let universalLink = userActivity.webpageURL else {
        Log("Not launched via universal links!")
        return
    }
        
    Log(String(format: "userActivities = %@", String(describing: userActivity)))
    Log(String(format: "universalLink = %@", universalLink.absoluteString))
        
    // Update UI
}

The above method doesn't get invoked and UI doesn't get updated.

This stackoverflow answer also confirms my understanding but I didn't get the URL. What is missing here?


Solution

  • I raised a TSI to AppleDTS and they informed me that the scene(_:continue:) method is for a UIKit app. For SwiftUI app, we have to use the onOpenURL(_:perform:) view modifier to handle universal links (and other URL based launches like file launch, deep link etc.) as shown below.

    WindowGroup {
        ContentView()
            .onOpenURL(perform: { (universalLink: URL) in
                        
                Log(String(format: "universalLink = %@", universalLink.absoluteString))
                 
                // Handle universal link 
            })
    }