ChimeHQ/AsyncXPCConnection
Concurrency support for NSXPCConnection
Usage
Given an XPC service like this:
@objc
protocol XPCService {
func method()
func errorMethod(reply: (Error?) -> Void)
func valueAndErrorMethod(reply: (String?, Error?) -> Void)
func dataAndErrorMethod(reply: (Data?, Error?) -> Void)
}You can use NSXCPConnection directly:
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)
}You can also make use of the RemoteXPCService type, which will remove the need for explicit typing of the service.
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)
}Ordering
The QueuedRemoteXPCService type is very similar to RemoteXPCService, but offers a queuing interface to control the ordering of message delivery. This is done via the AsyncQueuing protocol, for flexible, dependency-free support. If you need a compatible queue implementation, check out [Queue][queue]. And, if you know of another, let me know so I can link to it.
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)
}Alternatives
Contributing and Collaboration
I would love to hear from you! Issues or pull requests work great. Both a [Matrix space][matrix] and [Discord][discord] are available for live help, but I have a strong bias towards answering in the form of documentation. You can also find me on mastodon.
I prefer collaboration, and would love to find ways to work together if you have a similar project.
I prefer indentation with tabs for improved accessibility. But, I'd rather you use the system you want and make a PR than hesitate because of whitespace.
By participating in this project you agree to abide by the Contributor Code of Conduct.
[build status]: https://github.com/ChimeHQ/AsyncXPCConnection/actions [build status badge]: https://github.com/ChimeHQ/AsyncXPCConnection/workflows/CI/badge.svg [platforms]: https://swiftpackageindex.com/ChimeHQ/AsyncXPCConnection [platforms badge]: https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FChimeHQ%2FAsyncXPCConnection%2Fbadge%3Ftype%3Dplatforms [documentation]: https://swiftpackageindex.com/ChimeHQ/AsyncXPCConnection/main/documentation [documentation badge]: https://img.shields.io/badge/Documentation-DocC-blue [matrix]: https://matrix.to/#/%23chimehq%3Amatrix.org [matrix badge]: https://img.shields.io/matrix/chimehq%3Amatrix.org?label=Matrix [discord]: https://discord.gg/esFpX6sErJ [queue]: https://github.com/mattmassicotte/Queue
Package Metadata
Repository: ChimeHQ/AsyncXPCConnection
Stars: 60
Forks: 4
Open issues: 0
Default branch: main
Primary language: swift
License: BSD-3-Clause
Topics: concurrency, swift, xpc
README: README.md