Xcode 在XPC协议中使用自定义类
我正试图在带有回复的Xcode 在XPC协议中使用自定义类,xcode,macos,nsxpcconnection,Xcode,Macos,Nsxpcconnection,我正试图在带有回复的签名上使用我自己的类型编写XPC服务。该类型/类具有Xcode的主应用程序和XPC服务的“目标成员身份”。但是,我在调试输出中得到了不兼容的回复块签名,即使在withReply签名中使用了相同的类,但是Xcode目标不同,我将在下面解释 注意:这是在Swift中完成的,用于让我开始。除此之外,它们使用NSData而不是自定义类型 细节 出于这个问题的目的,我将使用下面的例子 自定义类-Tweet-该类符合NSSecureCoding协议,因此可以在主应用程序和XPC服务之间
签名上使用我自己的类型编写XPC服务。该类型/类具有Xcode的主应用程序和XPC服务的“目标成员身份”。但是,我在调试输出中得到了不兼容的回复块签名
,即使在withReply
签名中使用了相同的类,但是Xcode目标不同,我将在下面解释
注意:这是在Swift中完成的,用于让我开始。除此之外,它们使用NSData
而不是自定义类型
细节
出于这个问题的目的,我将使用下面的例子
- 自定义类-
Tweet
-该类符合NSSecureCoding
协议,因此可以在主应用程序和XPC服务之间传递
- XPC协议-
TweetTransfer
需要一种方法func-take(u-count:Int,withReply:((Tweet)->Void))
然后是所有常见的XPC样板文件,我在其中导出符合TweetTransfer
的对象。XPC服务似乎已启动,但随后它与主应用程序之间的传输失败
XPCWorker[11069:402719] <NSXPCConnection: 0x61800010e220> connection from pid 11066 received an undecodable message
更新
有关协议、remoteObjectProxy连接和Tweet对象的更多信息。这是用于XPC调用的协议:
@objc(TweetTransfer)
protocol TweetTransfer {
func take(_ count: Int, withReply: replyType)
}
typealias replyType = ((Tweet) -> Void)
为了方便起见,我使用了一个类型别名。然后,Tweet
对象非常简单,仅用于测试(尽管支持NSSecureCodeding有点复杂):
最后是我们调用remoteObjectProxy的点
guard let loader = workerConnection.remoteObjectProxyWithErrorHandler(handler) as? TweetTransfer else {
fatalError("Could not map worker to TweetTransfer protocol!")
}
var tweets = [Tweet]()
loader.take(1) { tweet in
tweets.append(tweet)
}
下面是完整的消息,但“wire”和“local”之间的唯一区别是参数1是
- 连线-
\u TtC17MainApp5Tweet
- 本地-
\u TtC23XPCWorker5Tweet
其中Xcode目标是不同的。这足以把它扔掉吗?那么,如何在应用程序及其XPC服务之间共享代码
这真的足以让它消失。Swift的名称空间使存档对象显示为不同的类。您可以通过使用声明Tweet对象来禁用名称间距
@objc(Tweet) class Tweet: NSObject, NSSecureCoding { ... }
@objc(name)
中的名称通常表示为在objc与Swift中表示不同名称的一种方式,但它也具有禁用Swift名称间距的效果
从
当您在Swift类上使用@objc(name)属性时,该类在Objective-C中不需要任何名称空间即可使用。因此,在将可架构的Objective-C类迁移到Swift时,此属性也很有用。由于存档对象在存档中存储其类的名称,因此应使用@objc(name)属性指定与Objective-C类相同的名称,以便新的Swift类可以取消存档旧的存档
另一种选择是将自定义对象移动到框架中。然后,该框架目标将成为名称空间,XPC和App都将引用框架中相同的名称空间/类。我可能可以帮助您。几天前,我刚刚处理过这个问题,但是在objective-c中。您能否在发件人向连接的remoteObjectProxy
发送消息的位置发布代码?还有你的Tweet
类的标题和实现谢谢,我添加了更多的信息。你找到解决方案了吗?
guard let loader = workerConnection.remoteObjectProxyWithErrorHandler(handler) as? TweetTransfer else {
fatalError("Could not map worker to TweetTransfer protocol!")
}
var tweets = [Tweet]()
loader.take(1) { tweet in
tweets.append(tweet)
}
@objc(Tweet) class Tweet: NSObject, NSSecureCoding { ... }