Skip to content

Instantly share code, notes, and snippets.

@jrsonline
Last active December 19, 2019 09:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrsonline/dd9799929e1aceb5d99e83fc6ac2b43b to your computer and use it in GitHub Desktop.
Save jrsonline/dd9799929e1aceb5d99e83fc6ac2b43b to your computer and use it in GitHub Desktop.
Simple implementation of RxSwift's "toBlocking" for Apple's Combine, now using the DispatchQueue
extension Publisher {
func toBlockingResult(timeout: Int) -> Result<[Self.Output],BlockingError> {
var result : Result<[Self.Output],BlockingError>?
let semaphore = DispatchSemaphore(value: 0)
let sub = self
.collect()
.mapError { error in BlockingError.otherError(error) }
.timeout(
.seconds(timeout),
scheduler: DispatchQueue.main,
customError: { BlockingError.timeoutError(timeout) }
).sink(
receiveCompletion: { compl in
switch compl {
case .finished: break
case .failure( let f ): result = .failure(f)
}
semaphore.signal()
},
receiveValue: { value in
result = .success(value)
semaphore.signal()
}
)
// Wait for a result, or time out
if semaphore.wait(timeout: .now() + .seconds(timeout)) == .timedOut {
sub.cancel()
return .failure(BlockingError.timeoutError(timeout))
} else {
return result ?? .success([])
}
}
}
enum BlockingError : Error {
case timeoutError(Int)
case otherError(Error)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment