Member preview

RxSwift foundation part 2: Observables and Subjects

Reactive programming has been in the picture for more than 20 years now, but it did not really start to gain momentum until the introduction of reactive extensions in 2009. Reactive extensions or Rx are available for several languages, and they look and behave the same for the most part across all these languages. Development began on RxSwift in February 2015, and it became the official reactive extension for Swift in August the same year.

Rx offers a common set of operators, to perform various tasks based on events in an asynchronous fashion, Rx typically implements two common patterns:

  • A subject maintains a list of dependents called Observers, and it notifies them of changes. NotificationCenter and KVO are also implementations of this observer pattern.
  • Rx also implements the iterator pattern, which is how sequences can be traversed. If you have spent time with Swift, then you will have definitely worked with the iterator pattern while trying to traverse over sequences and collections. We are talking about the same things here and in fact, in Rx, Everything is a Sequence:
Pretty much everything is a sequence of data or events or something that operates on observable sequences.

Note the term observable sequence; you will often read words like observable or sequence — these refer to the same thing. It’s a sequence that’s observable. We will refer to it as observable sequence.


Observable

An observable sequence is just a sequence.

The key advantage of an observable sequence over Swift’s standard sequence type is that it can also operate asynchronously.

In the next section we will understand the lifecycle of an Observable sequence and what it does during that lifetime.

Lifecycle of an observable:

An observable sequence can emit “things” known as events. It can emit zero or more events; when a value or collection of values is added to or put onto a sequence, it will send a next event containing that value or collection to its observers. This is known as emitting, and the values are referred to as elements. This works the same way as observable sequences of events such as taps or other recognised gestures.

If an error is encountered, a sequence can emit an error event containing an error type; this will terminate the sequence.
A sequence can also terminate normally and in doing so it will emit a completed event.

If at any point you want to stop observing a sequence, you can cancel the subscription by calling dispose() on it; this is like removing an observer in KVO or the NotificationCenter API, or you can also just add subscriptions to an instance of DisposeBag, which will take care of properly canceling subscriptions on deinit() for you.


Subject

Subject is a special type in RxSwift that can act as both of these:

  • An Observable sequence, which means it can be subscribed to
  • An Observer that enables adding new elements onto a subject that will then be emitted to the subject subscribers

There are four subject types in RxSwift, each with unique characteristics that you may find useful in different scenarios. They are as listed:

  • PublishSubject
  • BehaviorSubject
  • ReplaySubject
  • Variable

Let’s discuss each one of these subjects in turn.


A PublishSubject emits only new next events to its subscribers; in other words, elements added to a PublishSubject before a subscriber subscribes will not be received by that subscriber.

This concept of emitting previous next events to new subscribers is called replaying, and publish subjects DO NOT replay.

If terminated, though, a publish subject will re-emit its stop event, that is, a completed or error event to its new subscribers; actually, all subjects will re-emit stop events to new subscribers. If you are creating a real-time indicator, you won’t care what the last element was before a new subscription, you only want new elements coming in after the fact. PublishSubject will be useful in that scenario.


Sometimes you want new subscribers to always receive the most recent next event in the sequence even if they subscribed after that event was emitted; for this, you can use a BehaviorSubject.

A BehaviorSubject is initialised with a starting value, and then it replays to the new subscribers a next event containing the most recent elements or the initial value if no new recent elements have been added to it beforehand. Remember that if any subject type is terminated, it will reemit its stop event, whether that is a completed or a new event to its subscribers. For example, in a chat app, you might use a BehaviorSubject to pre-fill a new posts title text field beginning with the initial name untitled.


If you want to replay more than the most recent element on a sequence to new subscribers, you use a ReplaySubject.

A ReplaySubject is initialised with a buffer size and that value cannot be changed after initialisation. It will maintain a buffer up to the buffer size of the most recent next events, and it will replay the buffer to the new subscribers as if those events had happened immediately after each other, right after subscribing. It will also reemit its stop event to new subscribers. You can use replay subject to display as many as the five most recent search items whenever a search controller is presented.


A variable is essentially a wrapper around BehaviorSubject. It will replay a next event with the latest or initial value to new subscribers. A variable is guaranteed to never emit an error event and terminate. It also automatically completes when its about to be deallocated, which makes this subject unique. Unlike other subject types, a variable uses the dot “.” syntax to get the latest value or to set a new value onto it. You can access a variable’s BehaviorSubject by calling as Observable() on it.

I will cover all these subjects in code in the coming blogs, so do not worry if your current understanding is not yet crystal clear. This blog post was written to give you a brief introduction about what’s to come in the next blog.


For other updates you can follow me on Twitter on my twitter handle @NavRudraSambyal

To read in depth about Rx concepts and RxSwift you can follow the link to my book Reactive programming in Swift 4

Thanks for reading, please share it if you found it useful :)