Skip to content

Instantly share code, notes, and snippets.

Last active September 1, 2022 08:30
What would you like to do?
toBlocking equivalent for Combine's Publishers
extension Publisher {
func waitForCompletion(timeout: TimeInterval = 1.0, file: StaticString = #file, line: UInt = #line) throws -> [Output] {
let expectation = XCTestExpectation(description: "wait for completion")
var completion: Subscribers.Completion<Failure>?
var output = [Output]()
let subscription = self.collect()
.sink(receiveCompletion: { receiveCompletion in
completion = receiveCompletion
}, receiveValue: { value in
output = value
XCTWaiter().wait(for: [expectation], timeout: timeout)
switch try XCTUnwrap(completion, "Publisher never completed", file: file, line: line) {
case let .failure(error):
throw error
case .finished:
return output
func waitForFirstOutput(timeout: TimeInterval = 1.0, file: StaticString = #file, line: UInt = #line) throws -> Output {
return try XCTUnwrap(prefix(1).waitForCompletion(file: file, line: line).first, "", file: file, line: line)
Copy link

samwize commented Sep 1, 2022

Nice gist. I read your blog But your example don't work, because you set current.value = 2 before subscribing. Maybe subject behaviour changed since you wrote in 2020.

This extension works though, just must note that the values must send after a subscription is setup. Or at least send asynchronously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment