未从搜索关闭的应用程序调用 continueUserActivity

continueUserActivity not called from search closed app

我正在尝试使用 core spotlight 从 spotlight 搜索结果中打开一个视图控制器。

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray *restorableObjects))restorationHandler 
{

if(self.window.rootViewController){
    [self.window.rootViewController restoreUserActivityState:userActivity];
}

return YES;
}

当应用程序已经 运行 在后台运行时,这似乎有效,但是当它关​​闭并且我点击 Spotlight 搜索结果时,似乎没有调用此方法,我得到的行为是我的应用程序只是在主界面中启动。

你有什么建议让它在我的应用程序关闭时也能正常工作吗? 有没有办法调试正在发生的事情(因为我需要 运行 应用程序来附加调试器我不知道如何从搜索结果中模拟应用程序打开)?

妮可,

首先:有一种方法可以从 Xcode 启动您的应用程序而不是立即打开它:打开您的方案属性,转到 "run" 部分,然后在 "info" 下,有一个开关可以帮助您调试正在发生的事情:

"Wait for executable to be launched".

如果您激活此开关,您可以从 Xcode 启动应用程序,Xcode 将等到应用程序从搜索中打开,然后它会将调试器附加到它。

希望对您有所帮助!

伊万

如果应用程序已关闭,则不会调用 application:continueUserActivity:。相反,您会在应用程序中获得所有信息 launchOptions 字典:didFinishLaunchingWithOptions:

// In application: didFinishLaunchingWithOptions:
NSDictionary *activityDic = [launchOptions objectForKey:UIApplicationLaunchOptionsUserActivityDictionaryKey];  
if (activityDic) {
    // Continue activity here
}

这里是根据您的建议给出的完整答案。

// In application: didFinishLaunchingWithOptions:
NSDictionary *activityDic = [launchOptions objectForKey:UIApplicationLaunchOptionsUserActivityDictionaryKey];

if (activityDic) {
    if(self.window.rootViewController){
        NSUserActivity * userActivity = [activityDic valueForKey:@"UIApplicationLaunchOptionsUserActivityKey"];
        [self.window.rootViewController restoreUserActivityState:userActivity];
    }
}

如果您使用的是 Facebook SDK,并且在 didfinishlaunching 中,您正在 returning FBSDK,而不是纯文本,并且最后 returning 为真, 它可能会导致问题出现 continueuseractivity.

经过大量搜索,并尝试了不同的方法,我不得不 return 正确并评论此内容:

FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)

didFinishLaunchingWithOptions 需要 return YES 才能调用 continueUserActivity。

添加到应用程序末尾:didFinishLaunchingWithOptions:

NSDictionary *activityDictionary = launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey];
if (activityDictionary) {
    NSUserActivity *userActivity = activityDictionary[UIApplicationLaunchOptionsUserActivityTypeKey];
    if (userActivity) {
        return YES;
    }
}

return NO;

如果您的应用使用场景,请确保您已实现两个委托:

这个是针对在单击 link 时应用 不是 运行 的情况:

   func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
      // the url is expected to be in connectionOptions.userActivities.first?.webpageURL in case if its type is NSUserActivityTypeBrowsingWeb
   }

这一个适用于应用程序在后台或在前台的情况:

   func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
       // the url is going to be in userActivity.webpageURL
   }

如果您的应用不使用场景:

仔细检查这个方法调用,因为它在一段时间前发生了变化,遗留项目仍然有旧代码:

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

这是在我的案例中有效的调用:

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

(不要被 Xcode 的警告所欺骗,建议添加 private - 它不会有帮助)

查看 Apple's documentation about Universal Links 了解更多详情。

continue userActivity 已在最新的 swift 版本中更改。更改功能对我有用。

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

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

在新的 Swift 5 中有一个名为 SceneDelegate.swift 的新文件。 使用方法 scene(_ scene: UIScene, continue userActivity: NSUserActivity)