MVVM ❤️ RxSwift ❤️ Swift 4.x

Oberbaumbrücke, Berlin

Introduction

Oh yes! You’ve heard of the acronym MVVM over and over again and it stands for Model-View-ViewModel and I am focusing on this because I think it is the best and most realistic software architecture pattern for writing great iOS apps.

Why not MVC, MVP or VIPER ?

Well the intent of this article is not to go into a holy war with anyone but to share my personal opinion based on experience over the years as an iOS engineer.

MVC

The MVC stands for Model-View-Controller This is the most widely used architecture pattern within the iOS frameworks and most especially in the UIKit there are tuns of examples and things really gets messy when you have Storyboards within your application. MVC pattern is not bad, but the way Apple used this pattern in UIKit is totally unhealthy and unacceptable. The UITableView is a total tangle with zero separation of concerns. Apple is suppose to champion high quality code and good architectural design for it’s platforms. But this is not the case I must admit that with the bad examples shown in UITableViewDatasource & UITableViewDelegate is enough horror for you to avoid MVC totally.

MVP

So what problem do I have with this fantastic architecture pattern? First what’s MVP ? stands for Model-View-Presenter This architecture is widely within the Android development environment although it was first developed by Microsoft.

MVC vs MVP

As shown in the image above, we see that MVP is looking similar to MVC with one subtle difference related to changes within the model. In MVC the Model can communicate directly to the View oh yes! this was the horror that I was referring to eailier.

But wait MVP doesn’t make this mistake? No it doesn’t. MVP brings a very good separation of concerns and it’s perfect when you have to write a small app or prototype to show particular concept. The MVP has two main problems which are as follows:

  • The presenter tends to get involved with the UI related logics and becomes all-knowing Class
  • Secondly the relationship between the View and the Presenter is a one to one relationship. Which mean you can’t actually reuse the Presenter for other Views so it does have a big issue on reusability.

VIPER

Viper Architecture

VIPER stands forView-Interactor-Presenter-Entity-Router this pattern is highly scalable and has a brilliant separation of concerns. Let’s break it down:

  • View: Send user actions to presenter and displays data from presenter.
  • Interactor: Handles all the business logic. This is the core component.
  • Presenter: Queries the Interactor for data and sends it to the View
  • Entity: Holds model objects used by the Interactor.
  • Router: Handles all navigation logic.

VIPER is actually very good when working on a large code base because it enshrines the Single Responsibility Principle by helping you to decouple code for testability and reusability. It does this so well that you can consider yourself writing a “Ravioli” code :) if applied correctly.

So why am I not advocating for VIPER ? why do I think it’s not a good fit for iOS development ? Like I said before I don’t want to cause a holy war but here are my personal reasons:

  • High learning curve for new team members.
  • It’s highly opinionated by veteran engineers.
  • It doesn’t fit or match with UIKit
  • Over decoupled into becoming a “Ravioli” code base.
  • It’s overrated for what it offers when it comes to separation of concerns.

MVVM + RxSwift + Swift4.x

MVVM is my pick here in this war of architecture patterns. I am not advocating that it doesn’t have pitfalls, but I think it makes sense to use MVVM especially when writing iOS or Mac OS Apps. The original sin is thatMVC has been totally misused by Apple engineers in building tons of Spaghetti code within the UIKit. This was the problem all the other patterns were trying to solve. VIPER for me is an overkill, MVP has problem on reusability, Therefore MVVM cuts in between and it does blends in very well. Here are my key points:

  • Successful separation of concerns — Solid Principles where the View talks only to the ViewModel and the Model talks only to the ViewModel .
  • Reusability — one to many relationship between ViewModel and Views.
  • Testability — just mock the interface and you are good to go.
  • Low learning curve — fast to learn.
  • Less opinionated by veterans — almost everyone agrees.

RxSwift

Data binding is key part of MVVM and this is where RxSwift really play a great role in iOS App development. RxSwift is the Swift implementation of the ReactiveX API for asynchronous programming with observable streams of data. It makes life really easy when abstracting logics and the data bindings becomes like a kid’s play.

Putting it all together [MVVM, RxSwift, Swift4.x]

Enough of talk, let’s build a real world app with all the information we have at hand. I am choosing the iPhone Contact View where you have the names grouped into sections based on the first Character of the the lastname or firstname as show in the image bellow:

iPhone Contact Example

So let’s start by modelling a basic Person data as follows:

Model:

We are going to stick strictly with the MVVM pattern and as such our Model is where the business logic resides. The Model is responsible for the data access layer and any logic related. Yes the Model can contain computations.

The implementation of our interface is pretty straight forward as we can see from the code below:

ViewModel:

The ViewModel is responsible for all transformations, properties exposure to the View , communication or interaction mediation between the View & Model The ViewModel can be seen as the actual state of the underlying Model

The above code represents our interface requirement for the ViewModel

RxSwift — TableDatasource:

The RxSwiftbase implementation for UITableView doesn’t support the multi section UITableView . I find this a little bit strange. It has the implementation in a separate library called RxDataSources within the RxSwift Community repository. By the way I advise you to look at community repository there are lots of cool libraries that can make your life easy.

Albeit for this task I want to stick with only RxSwift so we are going to implement a utility Class called TableDatasource that will help us harness the multi section requirement as follows:

With that done we can now complete our ViewModel implementation based on the requirement.

View:

The View is responsible for displaying anything that the user can see. Yes your Autolayout logics should be in the View , and holds a ViewModel and uses it to communicate use interactions.

Is UIViewController a View or a Controller ? Well in my personal opinion I sole treat any UIViewController as a View . You are free to interpret it as you wish, but for me it remains a View in the context of MVVM

Composing MVVM:

Now we can actually plugin every thing together and see the MVVM come to live as follows:

Conclusion:

These are my personal opinions, if you are super fan of other patterns please feel free to make constructive suggestions and rationals, I am open for discussion and I hope I’ve at least entertained you with my rant :) Thanks for reading. You can find the code examples on my playground repository which covers this article, feel free to distribute and have fun.

Other Articles: