First steps into Rx

12. December 2017 Reactive Programming 0

When we started building a new app 2 years ago we thought we were pretty cool and hip. We started from scratch with a swift-only codebase and used libraries that had proven to be stable and well-supported. There is one practise we did not adopt: Reactive Programming. At the time it felt a bit new and scary and honestly we just couldn’t find a good reason to use it in our app. Why would we use this new way of programming that all our developers (and future developers) would have to learn?

Fast-forward 2 years later and reactive programming is everywhere. Every applicant at our company knows at least a little bit about it and you cannot visit a conference without someone talking about it. So it seemed like the right time to investigate it further and see if I could find a nice use-case for it in our App.

Starting Small

When adopting a new technology or a new library I like to do a very minimal implementation at first. I look for a use case that is ideal for that specific technology. For instance when we started using Realm I first implemented it for storing a simple list of data that had to be easily retrieved. The list was tiny and I could have used any other method of storing it (like serialising it to disk) but I knew that by introducing Realm to our codebase we would have the option of storing other, more complicated data later on.

For my first adventure in Rx I chose a similar simple use case. Autocomplete. We have a search field in our app that autocompletes city names or addresses while typing. This is something Rx excels at: taking a changing stream of data, typed text in the textfield and transforming it into something else: a list of autocomplete suggestion. Additionally, most Rx libraries have helper functions that can improve the user experience of such features even more.

The minimal implementation

First of all, I started by subscribing to any changes in the value of the “text” of the textfield.

This works as you would expect. The user types something in the textfield and the value is passed along to the “subscribe” closure that will then trigger the autocomplete logic. I won’t get too much into this logic since it is not Rx related, I chose to do all the network calls the “old-fashioned” way to keep this change as small as possible.

Bells and Whistles

In reality though, there are a few situations that you would also like to handle in this block of code to improve the user experience:

  • skip(1)
    When you subscribe to events of the textfield, the initial value of the field will also be processed. In our app we prefer not to show the autocomplete list immediately but to first show the user his or her’s previously searched locations. skip(1) makes sure the first value of the field is ignored.
  • debounce(0.3, scheduler: MainScheduler.instance)
    Since this feature is triggered by user input on a keyboard that then triggers a network call (to get the autocomplete options) we are careful about not doing these calls too often. If the user would type really fast, each change in the textfield would trigger a network call when in fact we only really care about the last change in the value. debounce(…) create a time window that cancels previous calls within that window.
  • distinctUntilChanged()
    Finally, we only really care about actual changes in the value of the textfield. A user could potentially type a value, then delete the final letter and quickly add the same letter back. The result would be a network call that would get the same autocomplete values that we already have on the screen. distinctUntilChanged() makes sure all values that are autocompleted are unique from call to call.

Summary

My tips for starting with Rx: Find a use case in your app that plays to the strengths of Reactive Programming and start with a minimal implementation.

More info and references