5

Method scene(_ scene: UIScene, continue userActivity: NSUserActivity) doesn't get called when the app is launched after the user clicks on a universal link.

It works fine when already launched app opens again after the user clicks on the universal link. The sample code:

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
        let incomingURL = userActivity.webpageURL,
        let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true),
        let path = components.path else {
            return
    }
    let params = components.queryItems ?? [URLQueryItem]()

    print("path = \(path)")
    print("params = \(params)")
}

I tried to use application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration, but it never gets called when the user clicks on the link:

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    if let scene = connectingSceneSession.scene, let userActivity = scene.userActivity {
        if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
            if let incomingURL = userActivity.webpageURL,
                let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true),
                let path = components.path {
                let params = components.queryItems ?? [URLQueryItem]()

                print("path = \(path)")
                print("params = \(params)")
            }
        }
    }
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

I tried to use scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions):

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    if let userActivity = scene.userActivity {
        self.scene(scene, continue: userActivity)
    }
}

I also tried the following methods:

func sceneDidBecomeActive(_ scene: UIScene) {
    if let userActivity = scene.userActivity {
        self.scene(scene, continue: userActivity)
    }
}

func sceneWillEnterForeground(_ scene: UIScene) {
    if let userActivity = scene.userActivity {
        self.scene(scene, continue: userActivity)
    }
}

But scene.userActivity is always nil there and I can't get userActivity.webpageURL.

How can we recognize that the link was clicked and the app was launched (not just opened)?

Dmitry
  • 317
  • 2
  • 11
  • Related (possibly the same underlying issue): https://stackoverflow.com/questions/58134706/shortcut-item-on-app-icon-not-working-with-ios-13 – rmaddy Oct 04 '19 at 22:45

3 Answers3

10

You almost had it:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    if let userActivity = scene.userActivity { // <-- not quite
        self.scene(scene, continue: userActivity)
    }
}

It's not in the scene; it's in the connectionOptions . Look in the connectionOptions.userActivities. (Though if what has happened is that the user clicked a link to launch us, I would expect to find the URL in the connectionOptions.urlContexts.)

matt
  • 447,615
  • 74
  • 748
  • 977
  • 1
    still not working for me. when the app is closed. (swiped from the recent apps) the dynamic link opens the app but the url is nil – Sergio Apr 02 '20 at 11:50
  • This answer seems outdated. The other answer about iterating over connectionOptions.userActivities worked for me. – Mick Oct 22 '20 at 21:58
  • @Mick Looking at what I actually wrote, it seems to me that that's exactly what I say too: "look in the `connectionOptions.userActivities`". Iterating is how you look. I don't go into more detail because it all seems so obvious. :) – matt Oct 22 '20 at 22:04
  • @matt Sorry! I just tried out the code block without reading your notes. :) You could just remove that... – Mick Oct 22 '20 at 22:33
3

Apple responded confirming that issue in iOS 13.

Dmitry
  • 13,126
  • 20
  • 95
  • 177
  • 2
    Do you have a link for the issue apple confirmed? The accepted answer does not work for me, when the app is closed and I click the dynamic link, the app opens but the url is nil. – Sergio Apr 02 '20 at 13:37
  • is it fixed by now? – Jalil Oct 14 '20 at 18:35
2

This worked for me:

func scene(_ scene: UIScene, willConnectTo _: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        for userActivity in connectionOptions.userActivities {
            if let url = userActivity.webpageURL { //ADD WHATEVER CONDITION YOU NEED
                //DO WHAT YOU NEED HERE
                break
            }
        }
    }

Basically the problem is that the universal link is "hidden" inside the connectionOptions so you have to search for it with the loop.

Dharman
  • 21,838
  • 18
  • 57
  • 107
Nicola Salvaro
  • 313
  • 2
  • 12