我正在尝试将Apple的XPC“ lowerCase”示例代码从Objective-C重建为Swift。我了解XPC会,但是我对Swift和Objective-C互操作性还比较陌生。
当我使用他们的确切示例代码时,该示例代码将String
从应用程序传递到目标,然后又传递回目标,它将起作用。但是,当我尝试用自己的自定义类Person
替换它时,出现了错误:
NSXPCConnection:...匿名监听器上的连接或 来自pid 4133的serviceListener:
在解码接收到的选择器upperCasePerson:withReply:的过程中捕获到异常,丢弃了输入 消息。
异常:解码参数0(#2的异常) 调用):
异常:decodeObjectForKey:类 未加载“ CombineCycle.Person”或不存在。
(演示应用程序名称为“ CombineCycle”)
Person
是一个Swift类,它继承自NSObject
并符合NSSecureCoding
。它具有name:String
的单个属性。随附的.swift
源文件包含在XPC目标的版本中。
该异常似乎很不言自明,但是我不确定我需要更改哪些构建设置,或者需要生成哪些文件来解决根本问题。
这只是一个演示应用程序。主应用程序是作为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
(私有类)无法反序列化...
__exceptionPreprocess + 250
objc_exception_throw + 48
_decodeObject + 1413
-[NSXPCDecoder _decodeObjectOfClasses:atObject:] + 63
_NSXPCSerializationDecodeInvocationObjectOnlyArgumentArray + 463
答案 0 :(得分:2)
问题似乎与NSCoder如何依靠类的名称进行归档和取消归档有关。在应用程序端对Person
对象进行编码时,使用的名称为<ModuleName.ClassName>
。
在服务中尝试反序列化时,ModuleName自然是错误的。在Person上使用@objc(Person)
设置Objective-C名称似乎有效。