Skip to content

Instantly share code, notes, and snippets.

@Segmentational
Created March 12, 2026 18:44
Show Gist options
  • Select an option

  • Save Segmentational/b3bde68eedf1a4e2e94c887d5c4df7aa to your computer and use it in GitHub Desktop.

Select an option

Save Segmentational/b3bde68eedf1a4e2e94c887d5c4df7aa to your computer and use it in GitHub Desktop.
XPC Session Example
import OSLog
import XPC
/// Executes an asynchronous end-to-end XPC round‑trip against the bundled XPC service
/// to validate connectivity, code‑signing requirements, request/response encoding,
/// and basic message handling.
///
/// The function:
/// - Creates an `XPCSession` targeting the XPC service with bundle identifier
/// `io.polyium.dx.XPT`.
/// - Configures a strict peer requirement that the service is signed by the same team
/// and matches the app’s signing identifier (via `Entitlements.identifier()`).
/// - Installs:
/// - An incoming message handler that logs whether a reply is expected and echoes a
/// simple test payload back to the sender.
/// - A cancellation handler that logs rich cancellation reasons.
/// - Activates the session, sends a test request (`XPCNS.Example.Input(first: 23, second: 19)`),
/// and awaits a typed response (`XPCNS.Example.Output`) using
/// `withCheckedThrowingContinuation`.
/// - Defers session cancellation to ensure resources are released promptly.
/// - Logs either the computed result on success or a descriptive error on failure.
///
/// ### Security
/// - Enforces that the peer is signed by the same team and matches the signing identifier,
/// mitigating the risk of connecting to an untrusted service.
///
/// - Important: The function assumes the presence of the `XPCNS.Example.Input` and
/// `XPCNS.Example.Output` types on both client and service, and that the service
/// understands and responds with the expected schema.
///
/// - Note: The session is always cancelled at the end of the request cycle, even on error,
/// to avoid leaking XPC resources.
///
/// - SeeAlso: `XPCSession`, `XPCReceivedMessage`, `XPCRichError`, `Entitlements.identifier()`
private func example() async {
let logger = Internal.Logger()
let session: XPCSession
let identifier: String?
let request: (any Encodable) = XPCNS.Example.Input(first: 23, second: 19)
var response: XPCNS.Example.Output?
let handler: (@Sendable (XPCReceivedMessage) -> (any Encodable)?)? = { message in
// Indicates if the service expects a response.
let reply: Bool = message.expectsReply
logger.info("XPC reply expectation is \(reply ? "expected" : "not expected").")
let request = XPCNS.Example.Input(first: 23, second: 19)
message.reply(request)
return nil
}
let cancellation: (@Sendable (XPCRichError) -> Void)? = { error in
logger.notice("XPC session cancelled: \(error)")
}
do {
identifier = try Entitlements.identifier()
} catch {
logger.warning("Unable to get signing identifier. Session will not enforce peer requirement(s). Error: \(error)")
identifier = nil
}
if let identifier {
logger.notice("XPC Session Peer Requirement Signing Identifier: \(identifier)")
} else {
logger.warning("Invalid or missing XPC peer requirement signing identifier. Session will not enforce peer requirement(s).")
}
do {
session = try XPCSession(
xpcService: "io.polyium.dx.XPT",
targetQueue: .global(qos: .utility),
options: .inactive,
requirement: .isFromSameTeam(andMatchesSigningIdentifier: identifier),
incomingMessageHandler: handler,
cancellationHandler: cancellation
)
response = try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<XPCNS.Example.Output, any Error>) in
defer { session.cancel(reason: Cancellation.completed) }
do {
try session.activate()
} catch {
response = nil
logger.error("Failed to activate XPC session. Error: \(error)")
continuation.resume(throwing: error)
return
}
do {
try session.send(request) { (result: Result<XPCReceivedMessage, XPCRichError>) in
do {
let value = try result.get()
let response = try value.decode(as: XPCNS.Example.Output.self)
continuation.resume(returning: response)
} catch {
continuation.resume(throwing: error)
}
}
} catch {
response = nil
logger.error("Received an error while sending XPC service request. Error: \(error)")
continuation.resume(throwing: error)
}
}
} catch {
logger.error("XPC add test failed: \(String(describing: error), privacy: .public)")
}
if let response {
logger.notice("XPC add result: \(response.result, privacy: .public)")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment