【问题标题】:cannot trigger continueUserActivity in Swift 3 / iOS 10在 Swift 3 / iOS 10 中无法触发 continueUserActivity
【发布时间】:2017-01-11 04:36:57
【问题描述】:

注意:我想出了大部分 - 请参阅最后的更新。还是有些混乱。

我正在尝试在 Swift 3 下的 Xc8b6 中实现 NSUserActivity 处理,但处理程序协议方法的方法签名存在问题。

在当前文档中,该方法被称为:

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

这与我在 swift 标题界面中看到的略有不同。在那里,restoredHandler 中的返回类型是 Swift.Void。

当我尝试这个时,我得到的错误是:

Objective-C 方法 'application:continue:restorationHandler:' 提供 通过方法 'application(_:continue:restorationHandler:)' 不匹配 需求选择器 ('application:continueUserActivity:restorationHandler:')

我意识到编译器警告现在不是很好,但我认为这意味着它找到了 Obj-C 方法签名,但不知何故我的论点不完全匹配。

我不知道还能去哪里。它匹配那里的东西 - 但 something 是错误的。随机猜测和检查对我没有帮助。

有趣的是,自动完成功能给了我一个不同的方法签名:

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

这个的好处是它可以编译。不太好的事情是,当我从 Spotlight 中选择索引项目并点击它以启动应用程序时,它不会被触发。

显然,我的 NSUserAction 正确识别了应用并启动了它。有什么我可能在这里丢失的东西不会触发restoreHandler 吗?请注意,这是从一个在 iOS 9 下运行良好的项目转换而来的。

我还在 WWDC 视频“搜索的新功能”中看到了协议方法签名的另一个版本。我试过了,它编译但也没有触发。

为了完善,这是我在 Swift 3 转换工具完成后得到的签名。它已编译,但从聚光灯启动时没有被触发:

func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]) -> Void) -> Bool

----更新-----

好的。所以上面提到的第一个方法签名是正确的。问题是我在 AppDelegate 的扩展中定义它。这在 Swift 2.x 中运行良好。

我已经把它向上移动了,一切都很好。但是我想更好地理解为什么在从扩展实现协议方法时会出现这些编译错误。它不再通过协议一致性了吗?如果我尝试将它添加到扩展程序中,我会收到一条错误消息,指出它是重复的,所以我认为不是这样。

【问题讨论】:

  • 将函数添加到协议扩展时,相当于将函数添加到原始协议定义中。这就是为什么你会得到一个重复的错误。如果协议扩展仅适用于特定类型,那就另当别论了
  • 这不是协议扩展。我可能应该创建一个新问题,因为我的旧问题得到了回答,而我现在有了一个新问题。简而言之 - 扩展只是: extension AppDelegate { 所以我正在扩展类,而不是协议。

标签: ios swift swift3 corespotlight nsuseractivity


【解决方案1】:

最初的问题是关于为什么 continueUserActivity 没有被调用(以及正确的签名是什么),所以我将在这里回答这个问题,以明确出了什么问题。

正确的签名是我在帖子顶部的签名:

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

请记住,此签名与 Xc8b6 中的自动完成功能不同,因此我怀疑其他人可能会遇到此问题并从此响应中受益。

我最初的问题是它没有编译,因为我是在扩展中进行的。为清楚起见:

extension AppDelegate {
  func application(_ application: UIApplication,
                   continue userActivity: NSUserActivity,
                   restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
    return true
  }
}

这适用于任何较旧的 iOS 9 / Swift 2.x 项目(具有较旧的 continueUserActivity 签名)。我仍然不确定为什么,但它不会在 Xc8 / Swift 3 的扩展中编译。

我把它移到了类作用域,现在可以正常工作了。

【讨论】:

  • 我在 AppDelegate 的任何可选方法中遇到了同样的问题。他们不再在扩展中构建。这非常烦人,并使 AppDelegate 超级脏。我认为可能是 func 具有像 fileprivate 这样的范围?所以扩展无法看到它们
  • @jeffro37 你的签名给了我错误。使用 Swift 4。
【解决方案2】:

所以,看起来从 Swift 3 开始,协议方法只能在协议附加到类的范围内访问。

这意味着UIApplicationDelegate协议内的所有AppDelegate方法只能在AppDelegate类或符合UIApplicationDelegate的AppDelegate扩展中访问

如果您尝试访问符合 UIApplicationDelegate 的类/扩展之外的 UIApplicationDelegate 方法,您将无法编译。

【讨论】:

    猜你喜欢
    • 2017-02-11
    • 1970-01-01
    • 2017-11-27
    • 2017-03-19
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 2017-02-25
    • 1970-01-01
    相关资源
    最近更新 更多