RxSwift course - basics

Photo by Quaritsch Photography / Unsplash

For 3 years I'm working with RxSwift on daily basis. It helps a lot with data manipulation and UI binding when MVVM is your architecture of choice. The framework gives developers flexibility and extendability. I made even an Rx version of filters used in an application that was using Metal. Yes, even metal view was using Rx for setting the new image to be displayed. Possibilities - limitless. You just have to start from the beginning and work your way to the top!

This will be the beginning, how to start, how it works, and basic operators and types. Nothing too hard and very fancy, but we have to start somewhere.

RxSwift library

The library, which you can find on Github, contains two main components - RxSwift and RxCocoa. First contains base framework implementations and most of the operators we will use during the course. RxCocoa provides many fancy extensions for most UIKit controls and views.

There are many RxSwift community repositories that provide even more ways to interact with UI elements, extensions for well-known third-party libraries, and more.

You can use Rx as standalone xcframework, cocoa pod, Carthage dependency, or my favorite and preferred - swift package.

Starter project

We will start with a simple console application. I made it available on my Github here. I added the RxSwift package there, that's it.

Observable

When working with RxSwift, you will interact with the Observable class. It produces a sequence of events, which in Rx world is named emitting. We can distinguish three main events (among few more, less important):

  • Value - the most important part, this type of event will provide you with a new value that was emitted.
  • Error - Observable can emit an error, in this case, the whole sequence is ended and no new elements will be produced.
  • Completed - this means that the sequence has ended and no new elements will come.

Creating Observable

There are many ways how Observable can be created, right now we will focus on easies one - by providing elements that will be emitted by hand:

import RxSwift
let firstObservable = Observable.just(1)
let secondObservable = Observable.from([1, 2, 3])
let thirdObservable = Observable.from(1...3)
Observable - factory methods

This three convenient methods will create simple observable, build and run application aaand... nothing happens.

Hot and cold

In reactive world we distinguish two types of sequences hot and cold.

  • hot observable is emitting values even when there is no subscription on sequence. Like UIButton tap event, it will be emitted even when we are not listening for its input.
  • cold observable will wait until there is at least one subscription to start emitting values. Default behavior of RxSwift Observable.

Subscribing for values

To start recieving values, we have to subscribe to Observable, easiest way is using .subscribe(...) method:

thirdObservable.subscribe(onNext: { print("New value! \($0)") }))
Subscribing to observable

Build and run. Now values are printed to console. As I mentioned before - cold observable starts emitting values after first subscription is created.

New value! 1
New value! 2
New value! 3
Program ended with exit code: 0
Console output

Disposing

RxSwift internal implementation keeps reference to your subscription, which results in retain cycle, this means that it will be forever in memory - causing unwanted memory leak. This is where disposing mechanism and DisposeBag is needed. When we create subscription disposable is created. This disposable is then used to break cycle and deinint subscription.

DisposeBag is very clever class - when it is being deinited - its disposes all of its disposables, that was put inside - hence bag:) Let's modify our code to get rid of warning and break the cycle!

let disposeBag = DisposeBag()
thirdObservable
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
Disposing subscription in dispose bag

And thats it, now you can experiment on your own in code and create your own sequences. All observables are generic, they can handle any type you want!

In next post we will learn how to dynamically send values to sequence.

Artur Gruchała

Artur Gruchała

I started learning iOS development when Swift was introduced. Since then I've tried Xamarin, Flutter, and React Native. Nothing is better than native code:)
Poland