{"id":20683159,"url":"https://github.com/chimehq/asyncxpcconnection","last_synced_at":"2025-08-22T02:30:48.804Z","repository":{"id":177252739,"uuid":"656149276","full_name":"ChimeHQ/AsyncXPCConnection","owner":"ChimeHQ","description":"Concurrency support for NSXPCConnection","archived":false,"fork":false,"pushed_at":"2025-03-17T13:37:15.000Z","size":68,"stargazers_count":50,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-07-25T13:37:57.057Z","etag":null,"topics":["concurrency","swift","xpc"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ChimeHQ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["mattmassicotte"]}},"created_at":"2023-06-20T10:53:59.000Z","updated_at":"2025-07-25T10:04:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"cfdd5d09-f256-431f-8475-14c3d7812c53","html_url":"https://github.com/ChimeHQ/AsyncXPCConnection","commit_stats":null,"previous_names":["chimehq/asyncxpcconnection"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/ChimeHQ/AsyncXPCConnection","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChimeHQ%2FAsyncXPCConnection","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChimeHQ%2FAsyncXPCConnection/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChimeHQ%2FAsyncXPCConnection/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChimeHQ%2FAsyncXPCConnection/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ChimeHQ","download_url":"https://codeload.github.com/ChimeHQ/AsyncXPCConnection/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChimeHQ%2FAsyncXPCConnection/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271575498,"owners_count":24783542,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-22T02:00:08.480Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["concurrency","swift","xpc"],"created_at":"2024-11-16T22:15:37.527Z","updated_at":"2025-08-22T02:30:48.532Z","avatar_url":"https://github.com/ChimeHQ.png","language":"Swift","funding_links":["https://github.com/sponsors/mattmassicotte"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n[![Build Status][build status badge]][build status]\n[![Platforms][platforms badge]][platforms]\n[![Documentation][documentation badge]][documentation]\n[![Matrix][matrix badge]][matrix]\n\n\u003c/div\u003e\n\n# AsyncXPCConnection\n\nSwift concurrency support for NSXPCConnection\n\nFeatures:\n- structured concurrency extensions for `NSXPCConnection`\n- convenience callbacks for better interfacing with Objective-C-based XPC protocols\n- `RemoteXPCService` for easier type-safety\n- `QueuedRemoteXPCService` for message ordering control\n\nYou might be tempted to just make your XPC interface functions async. While the compiler does support this, it is very unsafe. This approach does not handle connection failures and will results in hangs.\n\n## Usage\n\nGiven an XPC service like this:\n\n```swift\n@objc\nprotocol XPCService {\n    func method()\n    func errorMethod(reply: (Error?) -\u003e Void)\n    func valueAndErrorMethod(reply: (String?, Error?) -\u003e Void)\n    func dataAndErrorMethod(reply: (Data?, Error?) -\u003e Void)\n}\n```\n\nYou can use `NSXCPConnection` directly:\n\n```swift\nlet conn = NSXPCConnection()\nconn.remoteObjectInterface = NSXPCInterface(with: XPCService.self)\n\n// access to the underlying continuation\ntry await conn.withContinuation { (service: XPCService, continuation: CheckedContinuation\u003cVoid, Error\u003e) in\n    service.errorMethod() {\n        if let error = $0 {\n            continuation.resume(throwing: error)\n        } else {\n            continuation.resume()\n        }\n    }\n}\n\ntry await conn.withService { (service: XPCService) in\n    service.method()\n}\n\ntry await conn.withErrorCompletion { (service: XPCService, handler) in\n\tservice.errorMethod(reply: handler)\n}\n\nlet value = try await conn.withValueErrorCompletion { (service: XPCService, handler) in\n    service.valueAndErrorMethod(reply: handler)\n}\n\nlet decodedValue = try await conn.withDecodingCompletion { (service: XPCService, handler) in\n    service.dataAndErrorMethod(reply: handler)\n}\n```\n\nYou can also make use of the `RemoteXPCService` type, which will remove the need for explicit typing of the service.\n\n```swift\nlet conn = NSXPCConnection()\nlet remote = RemoteXPCService\u003cXPCService\u003e(connection: conn, remoteInterface: XPCService.self)\n\nlet decodedValue = try await remote.withDecodingCompletion { service, handler in\n    service.dataAndErrorMethod(reply: handler)\n}\n```\n\n## Ordering\n\nThe `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.\n\n```swift\nimport AsyncXPCConnection\nimport Queue\n\nextension AsyncQueue: AsyncQueuing {}\n\nlet queue = AsyncQueue()\nlet connection = NSXPCConnection()\nlet queuedService = QueuedRemoteXPCService\u003cXPCService, AsyncQueue\u003e(queue: queue, provider: { connection })\n\nqueuedService.addOperation { service in\n    service.method()\n}\n\nlet value = try await queuedService.addDecodingOperation { service, handler in\n    service.dataAndErrorMethod(reply: handler)\n}\n```\n\n## Alternatives\n\n- [SecureXPC](https://github.com/trilemma-dev/SecureXPC)\n- [SwiftyXPC](https://github.com/CharlesJS/SwiftyXPC)\n\n## Contributing and Collaboration\n\nI 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](https://mastodon.social/@mattiem).\n\nI prefer collaboration, and would love to find ways to work together if you have a similar project.\n\nI 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.\n\nBy participating in this project you agree to abide by the [Contributor Code of Conduct](CODE_OF_CONDUCT.md).\n\n[build status]: https://github.com/ChimeHQ/AsyncXPCConnection/actions\n[build status badge]: https://github.com/ChimeHQ/AsyncXPCConnection/workflows/CI/badge.svg\n[platforms]: https://swiftpackageindex.com/ChimeHQ/AsyncXPCConnection\n[platforms badge]: https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FChimeHQ%2FAsyncXPCConnection%2Fbadge%3Ftype%3Dplatforms\n[documentation]: https://swiftpackageindex.com/ChimeHQ/AsyncXPCConnection/main/documentation\n[documentation badge]: https://img.shields.io/badge/Documentation-DocC-blue\n[matrix]: https://matrix.to/#/%23chimehq%3Amatrix.org\n[matrix badge]: https://img.shields.io/matrix/chimehq%3Amatrix.org?label=Matrix\n[discord]: https://discord.gg/esFpX6sErJ\n[queue]: https://github.com/mattmassicotte/Queue\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchimehq%2Fasyncxpcconnection","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchimehq%2Fasyncxpcconnection","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchimehq%2Fasyncxpcconnection/lists"}