objective-c - 如何使 Swift 类在 XPC 服务中可用?

标签 objective-c swift macos xpc nsxpcconnection

我正在尝试将 Apple 的 XPC“lowerCase”示例代码从 Objective-C 重建为 Swift。我知道 XPC 会,但我对 Swift 和 Objective-C 的互操作性还比较陌生。

当我使用他们的确切示例代码(将 String 从应用程序传递到目标并返回)时,它起作用了。但是当我尝试用我自己的自定义类 Person 替换它时,我得到了错误:

NSXPCConnection: ... connection on anonymousListener or serviceListener from pid 4133:

Exception caught during decoding of received selector upperCasePerson:withReply:, dropping incoming message.

Exception: Exception while decoding argument 0 (#2 of invocation):

Exception: decodeObjectForKey: class "CombineCycle.Person" not loaded or does not exist.

(演示应用名称为“CombineCycle”)

Person 是一个 Swift 类,它继承自 NSObject 并符合 NSSecureCoding。它有一个 name:String 属性。它随附的 .swift 源文件包含在 XPC 目标的构建中。

异常似乎不言自明,但我不确定我需要更改哪些build设置,或者我需要生成哪些文件来解决潜在问题。

这只是一个演示应用程序。主应用程序创建为 Swift 应用程序,不包含任何 Objective-C 文件。 XPC 目标是使用 Xcode 的新目标功能创建的,该功能在 Xcode 11 中生成一个 Objective-C 框架。我用 Swift 实现替换了所有这些文件。

// Person.swift (Included in both targets)

@objc public class Person : NSObject, NSSecureCoding  {
  var name:String?

  init(_ name:String) {
    self.name = name
  }

  public static var supportsSecureCoding: Bool {
    return true
  }

  public required init?(coder: NSCoder) {
    self.name = coder.decodeObject(forKey: "name") as? String
  }

  public func encode(with coder: NSCoder) {
    coder.encode(self.name, forKey: "name")
  }
}

更新

XPC 服务能够很好地实例化 Person 的实例,因此包含了该类。问题似乎是 NSXPCDecoder(私有(private)类)无法反序列化它...

    __exceptionPreprocess + 250
    objc_exception_throw + 48
    _decodeObject + 1413
    -[NSXPCDecoder _decodeObjectOfClasses:atObject:] + 63
    _NSXPCSerializationDecodeInvocationObjectOnlyArgumentArray + 463

最佳答案

问题似乎与 NSCoder 如何根据类的名称进行归档和取消归档有关。当 Person对象在应用程序端编码,使用的名称是 <ModuleName.ClassName> .

当试图在服务中反序列化时,ModuleName 自然是错误的。使用 @objc(Person)在 Person 上设置 Objective-C 名称似乎有效。

关于objective-c - 如何使 Swift 类在 XPC 服务中可用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56585775/

相关文章:

php - httpd.conf 虚拟主机不工作

macos - 在 MacOSX 上,当指定无效的身份验证凭据时,QNetworkAccessManager 会进入无限循环

iphone - NSMutableArray 和 NSUserdefaults 问题 iPhone

objective-c - 如何在 objective-c 中反转 NSInteger 或 NSUInteger 的字节顺序

objective-c - Xcode - NSTimer 以随机间隔触发?没有一致性

ios - 将 CLLocationCooperative2D 坐标转换为 CGPoint Swift

objective-c - 基于 NSOutlineView 的 View 中的单元格是否在折叠时被释放?

swift - 添加多个对象实例 spritekit swift 3

ios - 应用程序如何存储/访问核心数据文件?

wordpress - 启用 https ssl wordpress 插件,某些 css 样式表不会在第一次尝试时加载。问题仅发生在 Mac 上