Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions Sources/AsyncXPCConnection/NSXPCConnection+Continuations.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Combine
import Foundation

enum ConnectionContinuationError: Error {
Expand Down Expand Up @@ -316,42 +317,45 @@ extension NSXPCConnection {

#if compiler(<6.0)
@_unsafeInheritExecutor
public func withDecodingCompletion<Service, Value: Decodable>(
public func withDecodingCompletion<Service, Value: Decodable, Decoder: TopLevelDecoder>(
function: String = #function,
using decoder: Decoder = JSONDecoder(),
_ body: (Service, @escaping @Sendable (Data?, Error?) -> Void) -> Void
) async throws -> Value {
) async throws -> Value where Decoder.Input == Data {
let data: Data = try await withValueErrorCompletion(function: function) { service, handler in
body(service, handler)
}

return try JSONDecoder().decode(Value.self, from: data)
return try decoder.decode(Value.self, from: data)
}
#else
public func withDecodingCompletion<Service, Value: Decodable>(
public func withDecodingCompletion<Service, Value: Decodable, Decoder: TopLevelDecoder>(
isolation: isolated (any Actor)? = #isolation,
function: String = #function,
using decoder: Decoder = JSONDecoder(),
_ body: (Service, @escaping (Data?, Error?) -> Void) -> Void
) async throws -> Value {
) async throws -> Value where Decoder.Input == Data {
let data: Data = try await withValueErrorCompletion(isolation: isolation, function: function) { service, handler in
body(service, handler)
}

return try JSONDecoder().decode(Value.self, from: data)
return try decoder.decode(Value.self, from: data)
}
#endif

#if compiler(>=6.0)
@available(*, deprecated, message: "please use withDecodingCompletion(isolation:function:_:)")
@available(*, deprecated, message: "please use withDecodingCompletion(isolation:function:using:_:)")
#endif
public func withDecodingCompletion<Service, Value: Decodable>(
public func withDecodingCompletion<Service, Value: Decodable, Decoder: TopLevelDecoder>(
function: String = #function,
on actor: isolated some Actor,
using decoder: Decoder = JSONDecoder(),
_ body: (Service, @escaping @Sendable (Data?, Error?) -> Void) -> Void
) async throws -> Value {
) async throws -> Value where Decoder.Input == Data {
let data: Data = try await withValueErrorCompletion(function: function, on: actor) { service, handler in
body(service, handler)
}

return try JSONDecoder().decode(Value.self, from: data)
return try decoder.decode(Value.self, from: data)
}
}
8 changes: 5 additions & 3 deletions Sources/AsyncXPCConnection/QueuedRemoteXPCService.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Combine
import Foundation

public protocol AsyncQueuing {
Expand Down Expand Up @@ -109,14 +110,15 @@ extension QueuedRemoteXPCService {
return try await task.value
}

public func addDecodingOperation<Value: Sendable & Decodable>(
public func addDecodingOperation<Value: Sendable & Decodable, Decoder: TopLevelDecoder>(
barrier: Bool = false,
using decoder: Decoder = JSONDecoder(),
operation: @escaping (Service, @escaping ValueErrorOperationHandler<Data>) -> Void
) async throws -> Value {
) async throws -> Value where Decoder.Input == Data {
let task: Task<Value, Error> = queue.addOperation(priority: nil, barrier: barrier) {
let conn = try await provider()

return try await conn.withDecodingCompletion { service, handler in
return try await conn.withDecodingCompletion(using: decoder) { service, handler in
operation(service, handler)
}
}
Expand Down
15 changes: 9 additions & 6 deletions Sources/AsyncXPCConnection/RemoteXPCService.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Combine
import Foundation

/// A thin wrapper around NSXPCConnection with a defined service type.
Expand Down Expand Up @@ -88,11 +89,12 @@ extension RemoteXPCService {
}

@_unsafeInheritExecutor
public func withDecodingCompletion<Value: Decodable>(
public func withDecodingCompletion<Value: Decodable, Decoder: TopLevelDecoder>(
function: String = #function,
using decoder: Decoder = JSONDecoder(),
_ body: (Service, @escaping (Data?, Error?) -> Void) -> Void
) async throws -> Value {
try await connection.withDecodingCompletion(function: function, body)
) async throws -> Value where Decoder.Input == Data {
try await connection.withDecodingCompletion(function: function, using: decoder, body)
}
#else
public func withValueErrorCompletion<Value: Sendable>(
Expand All @@ -119,12 +121,13 @@ extension RemoteXPCService {
try await connection.withErrorCompletion(isolation: isolation, function: function, body)
}

public func withDecodingCompletion<Value: Decodable>(
public func withDecodingCompletion<Value: Decodable, Decoder: TopLevelDecoder>(
isolation: isolated (any Actor)? = #isolation,
function: String = #function,
using decoder: Decoder = JSONDecoder(),
_ body: (Service, @escaping (Data?, Error?) -> Void) -> Void
) async throws -> Value {
try await connection.withDecodingCompletion(isolation: isolation, function: function, body)
) async throws -> Value where Decoder.Input == Data {
try await connection.withDecodingCompletion(isolation: isolation, function: function, using: decoder, body)
}
#endif
}