Swift 并发支持 NSXPCConnection
特性
NSXPCConnection
的结构化并发扩展RemoteXPCService
,更易于类型安全QueuedRemoteXPCService
,用于消息顺序控制您可能会想直接将 XPC 接口函数设为异步。虽然编译器支持这种做法,但它非常不安全。这种方法无法处理连接失败,并会导致程序挂起。
给定一个如下的 XPC 服务
@objc
protocol XPCService {
func method()
func errorMethod(reply: (Error?) -> Void)
func valueAndErrorMethod(reply: (String?, Error?) -> Void)
func dataAndErrorMethod(reply: (Data?, Error?) -> Void)
}
您可以直接使用 NSXCPConnection
let conn = NSXPCConnection()
conn.remoteObjectInterface = NSXPCInterface(with: XPCService.self)
// access to the underlying continuation
try await conn.withContinuation { (service: XPCService, continuation: CheckedContinuation<Void, Error>) in
service.errorMethod() {
if let error = $0 {
continuation.resume(throwing: error)
} else {
continuation.resume()
}
}
}
try await conn.withService { (service: XPCService) in
service.method()
}
try await conn.withErrorCompletion { (service: XPCService, handler) in
service.errorMethod(reply: handler)
}
let value = try await conn.withValueErrorCompletion { (service: XPCService, handler) in
service.valueAndErrorMethod(reply: handler)
}
let decodedValue = try await conn.withDecodingCompletion { (service: XPCService, handler) in
service.dataAndErrorMethod(reply: handler)
}
您还可以使用 RemoteXPCService
类型,这将消除对服务的显式类型指定的需求。
let conn = NSXPCConnection()
let remote = RemoteXPCService<XPCService>(connection: conn, remoteInterface: XPCService.self)
let decodedValue = try await remote.withDecodingCompletion { service, handler in
service.dataAndErrorMethod(reply: handler)
}
QueuedRemoteXPCService
类型与 RemoteXPCService
非常相似,但提供了一个排队接口来控制消息传递的顺序。这是通过 AsyncQueuing
协议完成的,用于灵活的、无依赖的支持。如果您需要兼容的队列实现,请查看 Queue。如果您知道其他的,请告诉我,我可以链接到它。
import AsyncXPCConnection
import Queue
extension AsyncQueue: AsyncQueuing {}
let queue = AsyncQueue()
let connection = NSXPCConnection()
let queuedService = QueuedRemoteXPCService<XPCService, AsyncQueue>(queue: queue, provider: { connection })
queuedService.addOperation { service in
service.method()
}
let value = try await queuedService.addDecodingOperation { service, handler in
service.dataAndErrorMethod(reply: handler)
}
我很乐意收到您的来信! Issue 或 Pull Request 非常有效。 Matrix space 和 Discord 都可用于实时帮助,但我强烈倾向于以文档的形式回答。您也可以在 mastodon 上找到我。
我更喜欢协作,如果您有类似的项目,我很乐意找到合作的方式。
我更喜欢使用制表符进行缩进以提高可访问性。 但是,我宁愿您使用您想要的系统并提出 PR,而不是因为空格而犹豫。
通过参与此项目,您同意遵守贡献者行为准则。