Reactive programming with RxSwift: How to get started

The evolution of technology has created the expectation that applications and systems should have a certain level of responsiveness, so freezing the user screen to do processing under the hood is just unacceptable nowadays. The way to address that is through asynchronous programming. The RxSwift library that can help you with that.

The RxSwift universe is vast. To enter it, you need to learn the reactive way of thinking, which will probably be a shift in your programming mindset. Reactive programming requires real understanding in proper use, starting with core concepts and the motivation behind this different approach to programming. No single article can teach you RxSwift or reactive programming. But discussion below offers you a roadmap, resources, and advice on recognizing which modules in your app are most suited to a reactive approach.

World Quality Report 2017-18: The state of QA and testing

Take RxSwift slow

Don't go all in when applying RxSwift to your project. Choose an isolated part of your app, migrate it to reactive, and then weigh the benefits, differences, advantages and disadvantages of this new approach.

Here are the parts of a system that are best suited to using RxSwift. I've sorted them in order of difficulty, from easiest to most challenging:

  • UI components. Observe changes in UI components and respond to them. Forget about delegates.
  • TableView's and CollectionView’s data sources  
  • Information-sharing between controllers and objects (the reactive approach uses observables)
  • The network layer (use observables instead of callbacks)
  • Extensions (wrap delegation using observables and provide reactive extensions for system classes)

I focus here on the entry level, so I only cover the first item: UI components, and the differences between the reactive and nonreactive approaches to a notification of a big sale. Want to follow along with the examples? Download the code I'll use in this discussion.

Nonreactive

The nonreactive version introduces something subtle but with the potential to cause a lot of harm—mutation. Mutation by itself is not a bad thing. But most of the time it is accompanied by its evil brother, side effects. In my sale example, I had to create an instance variable to store the last price and last unit. Doing so introduces mutation and the possibility of side effects in your code. Side effects and global variables can produce some of the most difficult-to-track problems in software development—as well as lots of headaches.

Reactive

The reactive version allows you to create observers to react upon emitted events on your observables; you can even combine two different observables and do a few transformations and filters on the emitted values, only reacting if the result is in the expected range. The best thing is that you can do all of that without mutation or side effects. The reactive approach limits mutation and side effects making easier to evolve and maintain the system.

But, wait a minute. What is an observable?

An observable is something that can asynchronously produce or emit a sequence of events over time. Other classes, known as observers, can subscribe (register) to these emitted events and react to them.

But why would you want to use this observable thing? To answer, I need to step back and bring some context.

Synchronous versus asynchronous

There are two types of code: synchronous and asynchronous. The first is intuitive; programming with it feels like the way you think, step by step, one thought after the other.


let file =readFile()
print(file)

The second type, asynchronous, is not so trivial. Working with it can be very challenging. Callbacks, delegation, and closures are just a few techniques you can use to work with async code, but sometimes those feel a bit verbose. Reactive programming is another way of working with your asynchronous code.


readFile() { file in
      …
}
print(“This will be executed before the return of the file”)

Reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change over time. In my example, I created an observable of "Floats" that emits a new value every time the price slider’s value changes.


priceSlider.rx.value
       .asObservable()

You can react to it through subscription, which is another way of saying, "Hey, sequence, I am interested in your events!" 


priceSlider.rx.value
        .asObservable()
       .subscribe(onNext: { newValue in
                   print(newValue)
        })

The gist URL shows a little different implementation. Its version first executes first a map operation, which is a transformation of the data that is later bound to the text label. Bind is another way of doing a subscription, sending the emitted events to an observer. In this case:


priceLabel
.rx.text

Observables do not start to send events until someone subscribes to them. They are sequences, and subscribing to them is more like calling next() in the first element of the sequence. Observables continue to emit events after their initial subscription until they emit an error or a completed event; only then are they terminated. But you can also manually terminate an observable by calling dispose() on it. Manually “disposing” every observable would be terrible, but there's an easier way to do it using DisposeBags, which are responsible for holding disposable references. Later, when the “bag” is about to be deallocated, it will call dispose() on every reference.

Now you can understand the following code:


.bind(to: priceLabel.rx.text)
       .addDisposableTo(disposeBag)

Resources

Some key resources that can help you understand some of the big ideas behind reactive programming and its implementation in RxSwift are:

  • Ray Wanderlich’s RxSwift. This book is, by far, the best RxSwift resource that I have ever bumped into. A must-have for anyone who would like to understand and apply RxSwift.
  • The Reactive Programming talk. Objc.io’s Swift Talks are known for amazing content. This video is the first addressing RxSwift.
  • Official site of RX frameworks
  • RxSwift GitHub page
  • Marble Diagrams, a beautiful way to understand sequences and transformations that happen over time

Your roadmap to becoming a better reactive programmer

There is still a lot to learn about observables and how to create them, interact, transform, and so on. RxSwift has many other concepts that you'll need to master before you can navigate it with confidence.

The next important concept is subjects, which are both observables and observers at the same time. That means they not only emit events but can subscribe and react to other observables.

Observables, subjects, and transformations together provide the basic RxSwift toolkit you need to handle 80% of the job. There is no way to convey all this information in a single article, but by this point you've got the fundamentals and should be ready to embark on your journey to become a better reactive programmer.

Do you have your own tips or suggestions, or just have a question? Post your comments below.

World Quality Report 2017-18: The state of QA and testing
Topics: Mobile