Before we fix this code, I’d like to briefly digress in order to mention the talk by Nataliya. I have been reading about MVVM for a while now, and was aware of the pattern’s association with RxSwift, but had not decided to make the leap away from MVC yet on any of my projects. One of the themes of Nataliya’s presentation which resonated with me was the idea that, like most patterns, MVVM is helpful in some areas, and unhelpful in others, and that’s okay. Your project doesn’t have to be completely MVC or completely MVVM. In other words, MVVM is not an architecture.

This idea helped me take the first step and start to implement MVVM a little at a time, and only where appropriate. I highly recommend you watch this full talk because it contains many helpful ideas, only one of which is discussed here.

So how could we use MVVM, and a more complete understanding of RxSwift, to improve the above code? First of all, I have to concede the following: Changes of the sort I am about to describe will not reduce the number of lines of code in your app, and are in fact likely to increase your line count. Some developers view LOC as the most important metric of code quality, and I typically feel it is a good one. However, I hope you will agree that extra lines constitute an acceptable sacrifice for what we hope to gain, namely:

Separation of concerns — our networking code should no longer interact directly with the UI layer. Declarative code — we will describe what the program should do rather than how it should be done. Isolation/minimization of side-effects — any side-effects should be represented as isolated Observable sequences rather than being embedded in callbacks alongside model updates.

First, we will discuss the main parts of my View Model. Instances of this type expose Observables for subscribing to changes on the model. Afterwards, we will look at how a view controller uses this type to bind UI elements.

The view model exposes three Observables: user , isLoading , and error . You’ll notice that these variables are generated from corresponding private members. These members can act as Observables and Observers, so we would not want to expose them directly. I won’t go into detail about the differences between Variable and PublishSubject , except to say that there are several different types of Subjects, each with unique benefits.

Additionally, the view model contains one public function which transforms an Observable<Void> to Observable<[User]> by flat-mapping an API request Observable, then binds the result to the variable: usersVariable . You’ll notice this function also affects the variable isLoadingVariable by toggling its underlying value before and after the network request.

Now, how is this used?

Here we see four functions which bind UI elements to the view model. These functions are called from viewDidLoad() , which looks like this: