Subscribe to last value after completed on RxSwift PublishSubject

Rodrigo Ruiz picture Rodrigo Ruiz · Sep 11, 2016 · Viewed 16.5k times · Source

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).

Answer

solidcell picture solidcell · Sep 12, 2016

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