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
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")
}
}
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With