在iOS 13中未调用application(... continue userActivity ...)方法

Mat*_*uya 6 ios swift ios13

嗨,我正在使用UniversalLink制作ios应用。

Universal Link可以正常工作,但是不调用回调方法

我的AppDelegate.swift在下面。

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
    }
}
Run Code Online (Sandbox Code Playgroud)

该方法在iOS 12 Simulator中被调用。

因此,仅在iOS 13中会出现此问题。

仅在iOS13中,此错误会在控制台中打印。

无法结束BackgroundTask:不存在标识符为1(0x1)的后台任务,或者它可能已经结束。中断UIApplicationEndBackgroundTaskError()进行调试。

因此,这可能是问题的原因。

我真的很感谢别人的帮助

Jan*_*Jan 38

就我而言,我在 Xcode 11 上启动了一个全新的项目,它使用SceneDelegate以及AppDelegate

看起来 UniversalLinks(可能还有其他几个 API)使用这个回调SceneDelegate

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { }
Run Code Online (Sandbox Code Playgroud)

而不是这个回调AppDelegate

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

一旦我在SceneDelegate所有方面都实施了这个,又开始按预期工作。我还没有尝试过,但我假设如果您的目标是 iOS 12 及更低版本,则可能需要实现这两种方法。

希望这可以帮助

  • 太棒了,我把 func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { } 放在 SceneDelegate 中,现在它绝对工作正常@Jan,有什么方法可以避免 AppDelegate 和 SceneDelegate 上代码重复的情况吗?谢谢 (3认同)

小智 37

我有一个类似的问题 SceneDelegate和通用链接,当应用程序刚刚启动时,我无法访问 NSUserActivity(在这种情况下,ios 13 中的后台 NFC 读取)。

正如@Jan 在回答中提到的,继续 userActivity 现在在SceneDelegate.

如果应用程序正在运行或在后台,即。关闭,通用链接将触发scene(_:continue:)委托。

如果应用程序不在后台,则代理不会启动通用链接scene(_:continue:)。相反,NSUserActivity可以从scene(_:willConnectTo:options:). 例如。

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    if let userActivity = connectionOptions.userActivities.first {
        debugPrint("got user activity")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,在 iOS 13.4.1 中,出于某种原因,“scene.userActivity”在这里为零。但你所说的效果很好:`let userActivity = connectionOptions.userActivities.first` (2认同)
  • 这个答案是黄金数周来一直在寻找的。感谢您 (2认同)

BRO*_*0UL 9

对于 SwiftUI 应用程序,现在有另一种方法来处理通用链接或任何 url,假设用户已经安装了该应用程序。

您可以简单地.onOpenURL()在主应用程序结构中的视图上使用修饰符。

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

    var body: some Scene {
        WindowGroup {
            MainContentView()
                .onOpenURL { url in
                    handleURL(url)
                }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并实现您自己的功能,例如:

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

}
Run Code Online (Sandbox Code Playgroud)

按照您的意愿处理通用链接。

对于不同的深度链接,即要处理安装前单击的链接,您仍然需要实现 SceneDelegate 方法。

  • 就是这个!甚至不知道有这个存在。苹果添加了很多新的修饰符来慢慢取代AppDelegate甚至SceneDelegate。这篇文章是我第一次展示这些修改器的强大和简单:https://peterfriese.dev/posts/ultimate-guide-to-swiftui2-application-lifecycle/#handling-deep-links (2认同)