All posts
iOS

RxSwift by Examples
#1 – The basics.

Łukasz Mróz

Łukasz Mróz

Swift is that kind of a language that feels good whatever you do with it. It connects good aspects of other languages, which makes Swift really flexible and relatively easy to understand by newcomers. That’s why you can find it being used with Object-Oriented Programming, but also with much more paradigms like the newest one Protocol-Oriented Programming, presented at WWDC’15. You don’t have to search much more to find that you can also use Functional Programming and Reactive Programming in Swift. Today and for another few weeks we will talk about the combination of the last ones, Functional Reactive Programming.

So what is that Functional Reactive Programming? In short this is using Reactive Programming with Functional Programming blocks (filter, map, reduce etc.). Guess what? Swift has them built-in already! And about the Reactive part, RxSwift covers us up.

Rx_Logo_M

RxSwift is a Reactive Extensions version written in Swift.

ReactiveX is a combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming

Basically you have to kinda change your perspective from statically assigning a value to the variable, to observing something that can and probably will change in the future.

Why-Jackie

You may ask “Why would I ever want to use it?”. Well, the answer is simple. It just simplify (sic!) your work. Instead of notifications, which are hard to test, we can use signals. Instead of delegates, which take a lot of place in code, we can write blocks and remove multiple switches/ifs. We also have KVO, IBActions, input filters, MVVM and many, many more which are handled smoothly by RxSwift. Remember, it’s not always the best way to solve a problem, but you kinda have to know when to use it to its full potential. I will try to present you some examples that you can use in your application.

Definitions.

First, we want to start off with some definitions. To better understand the logic we kinda have to go through the really basic stuff.

Your smartphone is an observable. It emits signals like Facebook notifications, messages, Snapchat notifications and so on. You are naturally subscribed to it, so you get every notification in your home screen. You can now decide what to do with that signal. You are an observer.

that_was_easy

Here we go, now you are fully prepared for the Example below 🎉

Example.

We will write City Searcher – type city in the search box and dynamically show us the list. When you write something in the search bar, we will dynamically try to fetch towns that starts with given letters and display it in a table view. Pretty simple, right? When you try to build dynamic search in your app, you always have to think about what can go wrong. For instance what if I will write really fast and will change my mind often? We would have many API requests which we have to filter. In real app you would have to cancel previous request, wait some time before sending another request, check for the phrase if it is the same as before and so on. Often times it creates huge logic, which looks pretty simple at the first sight. “It is just dynamic search, what could go wrong?”. Of course you could do it without using Rx, but lets see how we can write that logic using little to no code.

First we need to create project (if you don’t know how to do it, you can check out our other tutorials, for example here. Then we need to install CocoaPods and RxSwift + RxCocoa.  Example Podfile could look like this:

If we have every tool ready, we can start writing some code!

We’re gonna create our simple UI which is UISearchBar + UITableView.

City Seacher UI

Then we will need some arrays to save our cities. To reduce the logic in our code we will avoid using API, which will be covered in the next tutorials, and instead we will use two arrays, one with all cities and second one with shown cities. This will effectively act as an API in our case.

Then we will setup UITableViewDataSource and connect it with our shownCities variable:

As of now it should work as your normal UITableView so if we’d change the values of shownCities we should see it on the screen.

Right, now to the more interesting stuff. We will now observe the text in UISearchBar. It is really easy, because RxCocoa (which is extension of RxSwift)  has this built in for us! UISearchBar and many more controls given by Cocoa frameworks has support from Rx team. In our case, with usage of UISearchBar, we can use it’s property rx_text, which emits signals once the text in the search bar change. Cool! So how to observe this thing? Pretty simple! First we need to import RxCocoa & RxSwift.

Then onto the observing part! In viewDidLoad() we will add observing to the rx_text property of UISearchBar:

Perfect! And our dynamic search is working like that! subscribeNext is probably quite understandable – we are subscribing to the observable property, which produces signals. It’s like you’re telling your phone “Alrighty, now every time you got something new, show it to me”. And it will show you everything new. In our case we need only new values, but subscribe has more wrappers with events like onError, onCompleted etc.

what_if

The more interesting thing is the last line. When you subscribe to observables, often times you need to unsubscribe from it to avoid retain cycles. In Rx we have something called DisposeBag which is normally used to keep all things that you want to unsubscribe from in the deinit() process. For simple usage it is not needed, but the general rule of thumb is to always create that bag and add disposables to it. Next time I will show you how you can use small library to help you with that process, but for now we have to create our bag in order to compile our project:

So now, after compiling, we should have working application! After typing “O”, we should get our Oslo record in the table view. Excellent! But… what about all the things we were scared of? API spamming? Empty phrase? Delay? Right, we need to protect ourselves. Lets start with protecting our API backed. We need to add delay, that will fire up the request after X seconds after the typing, but only if the phrase didn’t change. Normally we could for instance use NSTimer fire it after delay or invalidate it if the new phrase is given. Not that hard, but still there is a room for error. But then what if we type for instance “O”, the results appears, we then change our mind and type “Oc”, but instantly go back to “O”, just before the delay and the API request fires up. In that case we have 2 exactly the same requests to API. In some cases we want that behavior, because maybe the database refreshes really fast. But normally it is not needed to fire up two the same requests in the span of lets say 0.5 seconds. To do that without Rx we would add some flag/last searched query and compare it with the new. Again not too much lines of code, but the logic grows and grows. In RxSwift we can do this with 2 lines of code. throttle() makes the delay effect on given scheduler, and distinctUntilChanged() protects us from the same values. If we connect it with the previous version it should look like this:

Glorious! But… I think we forgot about something. What if user typed something, refreshed the table view, and then deleted his phrase making new value that is empty? Yeah, we will send query with empty parameter… In our case we don’t want to do it so we have to somehow protect us against it. How? With the usage of filter(). You might know it already as it is built in Swift. But it raises the question: “Why do I have to use filter on one value? filter() works on collections!!!”. And this is a really good question! But don’t think about Observable as a value/object. It’s a stream of values, that will happen eventually. And therefore you will easily understand the usage of functional blocks. To filter our values we will do it as you would do it with an array of strings. Simply:

And that’s it! Complete code, which covers really not-that-easy logic, consists of 9 lines. Magic!

And that’s it for today! Pretty fun if you ask me! As always the full project is available on our github!

In the repository there are more example projects: some of them are already commented, some of them are not, but you can check them out to prepare for the next tutorial! Cheers! 😎

Read next article about RxSwift

» RxSwift by Examples #2 – Observable and the Bind.

Leave comment

  • Isuru Nanayakkara

    Thank you so much for this tutorial. I’ve been looking all over for a very basic RxSwift tutorial. Not only there are only a handful of tutorials about RxSwift as a whole, most of them just get way too complicated way too fast. This is the best one I found.

    • Łukasz Mróz

      Thank you so much for the kind words! ☺️