Skip to content

Instantly share code, notes, and snippets.

@Nillerr
Created February 18, 2022 09:50
Show Gist options
  • Save Nillerr/0de1b7ad8dc7d52a6363191631622951 to your computer and use it in GitHub Desktop.
Save Nillerr/0de1b7ad8dc7d52a6363191631622951 to your computer and use it in GitHub Desktop.
Implements the `.value` async property for `Future` available since iOS 15.0
import Combine
extension Publishers {
struct MissingOutputError : Error {}
}
extension Future where Failure == Never {
var value: Output {
get async {
var cancellable: AnyCancellable? = nil
var receivedValue: Output? = nil
return await withCheckedContinuation { continuation in
cancellable = sink { completion in
switch completion {
case .failure(let error):
continuation.resume(throwing: error)
case .finished:
if let receivedValue = receivedValue {
continuation.resume(returning: receivedValue)
}
}
cancellable?.cancel()
} receiveValue: { value in
receivedValue = value
}
}
}
}
}
extension Future {
var value: Output {
get async throws {
var cancellable: AnyCancellable? = nil
var receivedValue: Output? = nil
return try await withCheckedThrowingContinuation { continuation in
cancellable = sink { completion in
switch completion {
case .failure(let error):
continuation.resume(throwing: error)
case .finished:
if let receivedValue = receivedValue {
continuation.resume(returning: receivedValue)
}
}
cancellable?.cancel()
} receiveValue: { value in
receivedValue = value
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment