MVVM ❤️ RxSwift ❤️ Swift 4.x
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 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
UITableViewDelegate is enough horror for you to avoid
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.
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
Model can communicate directly to the
View oh yes! this was the horror that I was referring to eailier.
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
UIrelated logics and becomes all-knowing
- Secondly the relationship between the
Presenteris a one to one relationship. Which mean you can’t actually reuse the
Viewsso it does have a big issue on reusability.
VIPER stands for
View-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.
Interactorfor data and sends it to the
Entity:Holds model objects used by the
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
- 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 that
MVC 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
Viewtalks only to the
Modeltalks only to the
- Reusability — one to many relationship between
- Testability — just mock the interface and you are good to go.
- Low learning curve — fast to learn.
- Less opinionated by veterans — almost everyone agrees.
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:
So let’s start by modelling a basic
Person data as follows:
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 is responsible for all transformations, properties exposure to the
View , communication or interaction mediation between the
ViewModel can be seen as the actual state of the underlying
The above code represents our interface requirement for the
RxSwift — TableDatasource:
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
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 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.
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
Now we can actually plugin every thing together and see the
MVVM come to live as follows:
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.