application(...continue userActivity...) method not called in ios 13
Asked Answered
K

5

34

Hi I'm making ios app using UniversalLink.

Universal Link works fine, but callback method is not called.

My AppDelegate.swift is below.

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }


    func application(_ application: UIApplication,
                     willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        return true
    }

    // this method not called!!
    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        print("called")
        return true
    }
}

The method is called in iOS 12 Simulator.

So, the problem is occured only in iOS 13.

Only in iOS13 this error is printed in console.

Can't end BackgroundTask: no background task exists with identifier 1 (0x1), or it may have already been ended. Break in UIApplicationEndBackgroundTaskError() to debug.

So, this may be cause of the problem.

I'd really appreciate someone help

Keratitis answered 3/10, 2019 at 7:56 Comment(5)
I also have same problemDiffusivity
Any update about this issue?Turfman
Anyone found a solution to this issue?Phyllisphylloclade
@EmreÖnder I found one solution (check answer). Hopefully it was your same issuePhyllisphylloclade
@Turfman I found one solution (check answer). Hopefully it was your same issuePhyllisphylloclade
A
47

I had a similar issue with SceneDelegate and universal links where I could not get to NSUserActivity when the app was just launched (in this case Background NFC reading in ios 13).

As mentioned in the answer by @Jan, continue userActivity is now in the SceneDelegate.

If the app is running or in the background ie. closed, a universal link will fire the scene(_:continue:) delegate.

If the app is not in the background, a universal link won't fire up from the scene(_:continue:) delegate. Instead, the NSUserActivity will be available from scene(_:willConnectTo:options:). eg.

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    if let userActivity = connectionOptions.userActivities.first {
        debugPrint("got user activity")
    }
}
Ambie answered 17/12, 2019 at 6:54 Comment(1)
It is worth noting that scene.userActivity is nil here for some reason in iOS 13.4.1. But what you said works beautifully: let userActivity = connectionOptions.userActivities.firstSaxon
P
41

In my case, I started a brand new project on Xcode 11 which uses SceneDelegate as well as AppDelegate

Looks like UniversalLinks (and probably several other APIs) use this callback on the SceneDelegate:

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { }

Instead of this callback on the AppDelegate:

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { }

Once I implemented the one on SceneDelegate everything started working as expected again. I haven't tried it, but I'm assuming that if you are targeting iOS 12 and below, you might need to implement both methods.

Hope this helps

Phyllisphylloclade answered 17/10, 2019 at 5:13 Comment(5)
It's also not woking. Apple confirmed that issue in iOS 13. Of course, they are not going to fix it.Joon
Linked question: #58244384Joon
Awesome, I put func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { } in SceneDelegate and it's absolutly working fine now @Jan, Is there any way we can avoid this situation of code duplication over AppDelegate and SceneDelegate? ThanksStemson
@Stemson I don't thinkg you even need the code in the AppDelegate nowPhyllisphylloclade
@Phyllisphylloclade I removed SceneDelegate, it’s working fine after that.Stemson
L
11

For SwiftUI apps there is now another approach to handle a universal link or any url, assuming the user already has the app in installed.

you can simply use the .onOpenURL() modifier on the view in your main App Struct.

struct MySwiftUIApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

    var body: some Scene {
        WindowGroup {
            MainContentView()
                .onOpenURL { url in
                    handleURL(url)
                }
        }
    }
}

and Implement your own function such as:

@discardableResult func handleURL(_ url: URL) -> Bool {

}

to handle universal links how you wish.

For Differed deeplinking, i.e. to handle a link clicked before install you will still need to implement the SceneDelegate method.

Laroy answered 25/1, 2022 at 13:10 Comment(5)
This is it! Didn't even know that this existed. There are many new modifiers apple added to slowly replace AppDelegate and even SceneDelegate. This article was my first exposure of how powerful and easy these modifiers are: peterfriese.dev/posts/…Nobe
Thanks for this from '23. This is literally the first reference to this I've seen all day and is what I needed to get mine to work. Crazy. 👍Delicacy
I struggled with it some days. thanksLilah
this was the end of a whole day of searching/testing. I couldn't find any documentation about the relationship between this and the SceneDelegate's continue method but in my case, all other methods of the SceneDelegate were firing except the continue. This allowed me to overcome that even though it should have worked. Thanks a lot.Lampkin
It saved my time. Thanks bro. <3<3<3Unwind
A
2

Add this fucntion in your SceneDelegate class

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { if let url = userActivity.webpageURL { print(url) }}

Arkhangelsk answered 8/3, 2023 at 11:34 Comment(0)
L
0

iOS 14.0 added onContinueUserActivity(_:perform:). See this answer.

Logwood answered 15/6 at 20:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.