ReactiveX

So, you have heard about RxSwift. You see it ever so frequently in the wild. But whenever you try to wrap your head around it, it hurts. Here's what the Github page says about RxSwift:

Rx is a generic abstraction of computation expressed through Observable interface. This is a Swift version of Rx.

So great, you go and start watching that video. It's great, it is going to change programming for ever, but how do I use it. Let's try to break it down. RxSwift is an implementation of ReactiveX. In the most simple terms, the ReactiveX Observable model allows you to treat streams of asynchronous events with the same sort of simple, composable operations that you use for collections of data items like arrays. No more tangled webs of callbacks.

When building a frontend application, most of your tasks involve reacting to user interactions and doing something in response to them. It's a great use case for RxSwift. Let's take the example of a simple log in flow. Here are the events that you usually need to take care of:

  • Make a backend call to authenticate the user when he clicks login.
  • On success, get user's info from the backend.
  • Handle errors and show messages on UI.
APIProvider.request(.Login(emailTextField.trimmedText, passwordTextField.trimmedText)).flatMapLatest { token in  
    return APIProvider.request(.UserAccount)
}.subscribe { event in
    switch event {
    case .Next(let user):
        log.debug("Login success: \(user.user.email)")
        self.loginDidFinishWithUser(user.user)
    case .Error(let error):
        loginDidFailWithError(error)
    default:
        break
    }
}.addDisposableTo(disposeBag)

Let's break this up.

  1. .Login is the actual call to the backend to authenticate our user. You could use any implementation that you prefer (I have used Moya that plays really nice with RxSwift) and returns an Observable.
  2. If the login succeeds, it calls flatMap with an item of the observable. flatMap returns another observable which could then be subscribed and observed again using chaining. This is where we make another request to the backend for the UserAccount if our login was successful.

Finally, with .subscribe, we start listening to the events from this Observable chain. The event could be .Next when a new element is emitted by the Observable. This means that the request was successful. It could be .Error in case of an error and .Completed when the observable completes.

Let's assume we want to consider failure status codes as .Error events on the observable. This becomes really easy with RxSwift. All we need is a filterSuccessfulStatusAndRedirectCodes from Moya in the chain after our request. If you want to map the response into Swift objects, it's got you covered there as well. Just use .mapObject(Class) from Moya-ObjectMapper in the chain. You see how easy it was to make changes later by just adding things in the Observable chain?

This is a very simple example of how to manage simple network calls in your application with RxSwift. It requires a bit of getting used to, but it's well worth the effort. It helps write maintainable code that is easy to read or refactor at a later stage. If at any point, we want to add another call to the chain, we would simply need to add another flatMap operator in the Observable chain.

This is supposed to be a very simple primer to RxSwift and in no way even close to the covering the myriad of operators available at your convenience.