Reputation: 4355
I'm looking for something like this:
let observable = PublishSubject<String>()
observable.onNext("1")
observable.onCompleted()
_ = observable.subscribeNext { s in
print(s)
}
So I want to subscribe to the Observable after it has already been completed and still get the values (or just the last value).
Upvotes: 11
Views: 25170
Reputation: 7729
You're using the wrong Subject
to get what you want. Take a look at the descriptions of the Subjects:
PublishSubject: Broadcasts new events to all observers as of their time of the subscription.
ReplaySubject: Broadcasts new events to all subscribers, and the specified bufferSize number of previous events to new subscribers.
BehaviorSubject: Broadcasts new events to all subscribers, and the most recent (or initial) value to new subscribers.
Variable: Wraps a BehaviorSubject, so it will emit the most recent (or initial) value to new subscribers. And Variable also maintains current value state. Variable will never emit an Error event. However, it will automatically emit a Completed event and terminate on deinit.
So, don't use PublishSubject
, since it only broadcasts new events upon subscription.
You can use ReplaySubject
to get all previous events, or you can use ReplaySubject
, BehaviorSubject
, or Variable
to get the most recent value.
let disposeBag = DisposeBag()
// ALL previous events
let subject = ReplaySubject<String>.createUnbounded()
// or use this to get just the last, say, 4:
// let subject = ReplaySubject<String>.create(bufferSize: 4)
// or use one of these to get the most recent:
// let subject = ReplaySubject<String>.create(bufferSize: 1)
// let subject = BehaviorSubject(value: "blah")
// let subject = Variable("blah")
subject.onNext("blah")
subject.onNext("foo")
subject.onCompleted()
subject
.asObservable()
.subscribeNext { print($0) }
.addDisposableTo(disposeBag)
Outputs:
blah
foo
Upvotes: 33