Last active
February 20, 2020 16:27
-
-
Save erenkabakci/2cbdef52e9a821029e77513222f20349 to your computer and use it in GitHub Desktop.
PublishersPlayground
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Combine | |
import Foundation | |
struct SomeError: Error {} | |
// 1- Subject scenarios | |
let currentValueSubject = CurrentValueSubject<String, Error>("foo") | |
let passThroughSubject = PassthroughSubject<String, Error>() | |
currentValueSubject.send("Loo") // receiveValue of the subscriber will be called when "sink", receiveCompletion won't be called, the subscription is still active | |
passThroughSubject.send("Loo") // receiveValue of the subscriber will be called if "sink" before this line, receiveCompletion won't be called, the subscription is still active | |
currentValueSubject.send(completion: .finished) // receiveValue won't be called, receiveCompletion will be called with finish, the subscription and "sink" terminates | |
passThroughSubject.send(completion: .finished) // receiveValue won't be called, receiveCompletion will be called with finish, the subscription and "sink" terminates | |
// -------- you can send once completion only, either .finished or .failure, after that the subscription terminates -------- | |
currentValueSubject.send(completion: .failure(SomeError())) // receiveValue won't be called, receiveCompletion will be called with failure, the subscription and "sink" terminates | |
passThroughSubject.send(completion: .failure(SomeError())) // receiveValue won't be called, receiveCompletion will be called with failure, the subscription and "sink" terminates | |
// 2- Publisher scenarios | |
var publisher: AnyPublisher<String, Error> | |
var publisherNeverError: AnyPublisher<String, Never> | |
var publisherNeverValue: AnyPublisher<Never, Error> | |
var publisherNeverValueNeverError: AnyPublisher<Never, Never> | |
// 2a- ------ Publishers which are possible for asignments to <String, Error> ------- | |
publisher = currentValueSubject.eraseToAnyPublisher() // receiveValue of the subscriber will be called immediately when "sink", receiveCompletion won't be called, the subscription is still active | |
publisher = passThroughSubject.eraseToAnyPublisher() // receiveValue of the subscriber will be called if "sink" is before this line, receiveCompletion won't be called, the subscription is still active | |
publisher = Future<String, Error> { promise in | |
promise(.success("Foo")) | |
}.eraseToAnyPublisher() // receiveValue will be called immediately when "sink", receiveCompletion will also be called right after, with .finished, the subscription is terminated | |
publisher = Future<String, Error> { promise in | |
promise(.failure(NSError())) | |
}.eraseToAnyPublisher() // receiveValue won't be called, receiveCompletion will be called with .failure, the subscription is terminated | |
// 2b- ------ Publishers possible for <String, Never> assignments ------- | |
publisherNeverError = Just("Foo").eraseToAnyPublisher() // receiveValue will be called immediately when "sink", receiveCompletion won't be called, the subscription is still active | |
publisherNeverError = Empty(completeImmediately: true).eraseToAnyPublisher() // receiveValue won't be called, receiveCompletion will be called with finish, the subscription and "sink" terminates | |
publisherNeverError = currentValueSubject.replaceError(with: "Boo").eraseToAnyPublisher() // receiveValue will be called immediately with the value "Boo" when "sink", receiveCompletion won't be called, the subscription is still active | |
publisherNeverError = passThroughSubject.replaceError(with: "Boo").eraseToAnyPublisher() // receiveValue will be called if "sink" is before this line, receiveCompletion won't be called, the subscription is still active | |
// 2c- ------ Publishers possible for <Never, Error> assignments -------- | |
publisherNeverValue = currentValueSubject.ignoreOutput().eraseToAnyPublisher() | |
currentValueSubject.send(completion: .finished) // receiveValue won't be called since the output is ignored, receiveCompletion will be called with .finished, the subscription and "sink" terminates | |
publisherNeverValue = passThroughSubject.ignoreOutput().eraseToAnyPublisher() | |
passThroughSubject.send(completion: .failure(SomeError())) // receiveValue won't be called since the output is ignored, receiveCompletion will be called with .failure, the subscription and "sink" terminates | |
publisherNeverValue = Fail(error: SomeError()).eraseToAnyPublisher() // receiveValue won't be called, receiveCompletion will be called with .failure, the subscription and "sink" terminates | |
// 2d- ------ Publishers possible for <Never, Never> assignments -------- | |
// This is a very rare scenario since why would you want a stream which never receives a value but also never error. So the only possibility is to receiveCompletion with .finished | |
// In this case any subject with sendCompletion or Future.ignoreOutput would do it. | |
publisherNeverValueNeverError = Future<String, Error> { promise in | |
promise(.success("Foo")) | |
} | |
.catch { _ in Just("Foo") } | |
.ignoreOutput() | |
.eraseToAnyPublisher() | |
// Other publisher scenarios | |
let _ = Empty<String, Error>() // never receives value, never completes, subscription is always active, open stream forever! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment