objective-c - 如何在 XPC 服务中提供 Swift 类?
问题描述
我正在尝试将 Apple 的 XPC“小写”示例代码从 Objective-C 重建为 Swift。我了解 XPC 会,但我对 Swift 和 Objective-C 互操作性还比较陌生。
当我使用他们的确切示例代码时,它将 aString
从应用程序传递到目标并返回,它可以工作。但是当我尝试用我自己的自定义类替换它时Person
,我得到了错误:
NSXPCConnection: ... 来自 pid 4133 的匿名侦听器或服务侦听器上的连接:
在解码接收到的选择器 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
解决方案
这些问题似乎与 NSCoder 如何通过依赖类的名称进行归档和取消归档有关。当Person
对象在应用程序端编码时,使用的名称是<ModuleName.ClassName>
.
当试图在服务中反序列化时,ModuleName 自然是错误的。在 Person 上使用@objc(Person)
来设置 Objective-C 名称似乎是有效的。
推荐阅读
- node.js - Error: connect ECONNREFUSED 200.142.86.219:443 using google cloud functions随机出现
- c++ - 使用 C++ 通过三角分解求解线性系统
- css - css 过渡超出水平中心。现在它只是退出而不是动画
- database-design - 优化子句查询cassandra?
- javascript - 如何从 Blogger 的 javascript 中的站点地图生成器中排除标签
- python - 子类模型无法在 tensorflow 2 中使用 to_json() 保存?
- github - 如何在 GitHub README.md 文件上显示 KaTex - 输出?
- python - 决策树节点中的值属性的浮点数(scikit-learn,randomforest)
- sql - 角色和特权有什么区别
- amazon-web-services - 开发简单的云数据处理系统