I have an old callback API, which has a newValue
callback handler emitting one value at a time, and a completion
callback, containing an Error
or nil, if success.
Unfortunately, calling collecting
blocks until the API sent all values!
func<T> collecting(newValue: @escaping (T) -> Void, completion: @escaping (Error?) -> Void) { ... }
func publisher<T>(_ type: T.Type) -> AnyPublisher<T, Error> {
let subject = PassthroughSubject<T, Error>()
collecting(newValue: { value: T -> Void in
subject.send(value)
} completionHandler: { error: Error? -> Void in
if let error = error {
subject.send(completion: .failure(error))
} else {
subject.send(completion: .finished)
}
}
return subject.eraseToAnyPublisher()
}
This code above does not work, because calling collecting
blocks, and the return statement is only called with finished
.
How can you implement such API in Combine?
I don't want to use any DispatchQueue.async
, because scheduling should be handled by Combine.