Universal link not passed to SceneDelegate when app runs in the background

I have a SwiftUI app which supports a launch from a configured universal link. I'm following this documentation.

When the app is not running and I tap a universal link, app launches. This proves the association of the website and the app.

Now, when the app is already running in the background, and then I tap a universal link, things don't work as expected. Quoting from the documentation

If your app has opted into Scenes, and your app is not running, the system delivers the universal link to the scene(:willConnectTo:options:) delegate method after launch, and to scene(:continue:) when the universal link is tapped while your app is running or suspended in memory.

I've implemented scene(_:continue:) in my SceneDelegate but it never gets invoked. I'm pasting some relevant logs

AppDelegate.application(_:willFinishLaunchingWithOptions:)
AppDelegate.application(_:didFinishLaunchingWithOptions:)
AppDelegate.application(_:configurationForConnecting:options:)
SceneDelegate.scene(_:willConnectTo:options:)
SceneDelegate.sceneWillEnterForeground(_:)
NSNotificationName(_rawValue: UIApplicationWillEnterForegroundNotification)
SceneDelegate.sceneDidBecomeActive(_:)
NSNotificationName(_rawValue: UIApplicationDidBecomeActiveNotification)

Now, I background the app...

SceneDelegate.sceneWillResignActive(_:)
NSNotificationName(_rawValue: UIApplicationWillResignActiveNotification)
SceneDelegate.sceneDidEnterBackground(_:)
NSNotificationName(_rawValue: UIApplicationDidEnterBackgroundNotification)

App runs in the background... Now, I tap a Universal link

SceneDelegate.sceneWillEnterForeground(_:)
NSNotificationName(_rawValue: UIApplicationWillEnterForegroundNotification)
SceneDelegate.sceneDidBecomeActive(_:)
NSNotificationName(_rawValue: UIApplicationDidBecomeActiveNotification)

As shown in the logs above, there is no trace of scene(_:continue:).

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))
        
        StaticContext.dataFromMainApp = universalLink.absoluteString
        StaticContext.viewController.updateLabelWithLink()
    }

What am I missing here?

Answered by GangOrca in 781085022

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 
        })
}
Accepted Answer

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 
        })
}
Universal link not passed to SceneDelegate when app runs in the background
 
 
Q