RxSwift Subjects

Dimitris Kalaitzidis
3 min readFeb 26, 2019

Add new values to observable? Say hello to subjects.

A common need when developing apps is to manually add new values onto an observable at runtime that will be emitted to subscribers. What we want is something that can act as both an observable and as an observer.

This something is called a Subject.

Subjects act as both an observable and an observer. They can receive .next events, and each time it receives an event, it turns around and emits it to its subscriber.

There are four subject types in RxSwift

  • PublishSubject: Starts empty and only emits new elements to subscribers.
  • BehaviorSubject: Starts with an initial value and replays it or the latest element to new subscribers.
  • ReplaySubject: Initialized with buffer size and will remain a buffer of elements up to that size and replay it to new subscribers.
  • BehaviorRelay: Wraps a BehaviorSubject, preserves its current value as a state, and replays only the latest/initial value to new subscribers.

PublishSubject

Let’s create a PublishSubject, add some subscribers on it and add some values on runtime.

Remember the PublishSubject emits new elements to subscribers, so in order for a subscriber to get a value, a .onNext event must occur after the subscription.

Let's create a publishSubject and subscribe to it

The output:

first: next(1)
first: next(2)
first: next(3)
second: next(3)
first: next(4)
second: next(4)
second: next(5)
third: next(5)

It makes sense right? The subscriber waits for .onNext events in order the get the values. After subscription, the subscriber will receive values from the PublishSubject until the subscription is disposed.

BehaviorSubject

Using the same code as before with the only difference of the subject type.

Let’s create a BehaviorSubject and see the differences from PublishSubject

The output:

first: next(Initial Value)
first: next(1)
first: next(2)
second: next(2)
first: next(3)
second: next(3)
first: next(4)
secord: next(4)
third: next(4)
secord: next(5)
third: next(5)

As you can see the main difference of the output is that when a subscription occurs, the subscriber prints the value instantly. Remember?

A BehaviorSubject starts with an initial value and replays it or the latest element to new subscribers.

ReplaySubject

Creating a ReplaySubject with bufferSize of 5

The output:

first: next(1)
first: next(2)
second: next(1)
second: next(2)
first: next(3)
second: next(3)
first: next(4)
second: next(4)
third: next(1)
third: next(2)
third: next(3)
third: next(4)
second: next(5)
third: next(5)

As you can see, when a new subscription occurs, the subject emits the previous values also instead of current / new one. How many? Depends on the bufferSize value. It’s very clear on the third subscription how it works.

BehaviorRelay

Creating a BehaviorRelay, the output is the same like BehaviorSubject

The output:

first: next(Initial Value)
first: next(1)
first: next(2)
second: next(2)
first: next(3)
second: next(3)
first: next(4)
secord: next(4)
third: next(4)
secord: next(5)
third: next(5)

BehaviorRelay replaced RxSwift’s Variable because is marked for depreciation. The BehaviorRelay subject is BehaviorSubject wrapper with one major difference. You add values with .accept method, lies on RxCocoa so a new import is needed and cannot be terminated with an .error or .completed event.

That was a quick overview of RxSwift subjects. If you enjoyed this article you can follow me on Github (https://github.com/dkalaitzidis/) or Twitter (https://twitter.com/kalaitzidis34).

You can read my previous article, Introduction to Rx here: https://medium.com/@dimitriskalaitzidis/introduction-to-rx-ac2887d5f474

References: reactivex.io, RxSwift: Reactive Programming with Swift (raywenderlich)

--

--