The perfect MVVM for an iOS app exists? (Part 1 of 3)

MoureDev
Jeff Tech
Published in
5 min readApr 17, 2020

Part 1 — Introduction and context

I want to detail the process of adapting the MVVM pattern to the specific needs of an app (Jeff, in our case), following the maxim that, above all, you must find a solution that adapts to the flow of the project and your team. This article is not intended as a guide to iOS architecture, but rather a reflection of the evolution and maturity of a project.

Introduction

Historically, and until recently (thanks to Combine), Apple has not had, among its practices, guide developments on its platforms under an advanced pattern or architecture (I mean, outside of Model View Controller). This has forced the community to find their own solutions.

Based on the MVM that Xcode “facilitates” when we create a project, there comes a time (or so I think) in the life of every programmer in which it is considered that it is time to take the next step and find that new organization that is responsible to undock the elements of your app. After that moment, one will start the search for that next level, and will find patterns like MVP, MVVM, VIPER, etc. and terms like Interactor, Router, Presenter, etc. Below you won’t know which one is better, and what’s worse, you may not fully understand their differences, similarities, and strengths. You may even, overwhelmed, believe that your MVC is enough.

I want to clarify that personally I do not believe that there is one architecture better than another. We should not be dragged because this app or first-rate team uses this or that. The first thing is to be aware of the needs of the project, its teams and how the evolution of both can affect the development process. Having said that, perhaps your MVC was enough.

Context

In our case, it was clearly NOT enough. The company grew (from 7 to 700 employees in four years), with it, the engineering team and the lines of business (the term “Super App” appeared 🤘🏼). Our app, which wanted to gain a foothold in the market, and after achieving this, had to prepare to support exponential growth. By focusing, one of the many steps was to get rid of our MVC and adopt a new design pattern. It was time to deeply analyze which would best suit our needs.

After a long time, MVP seemed insufficient, VIPPER too abstract and MVVM incomplete. I repeat, always aiming at our app, which in short, is a set of several small apps with not always a common logic.

Finalizing the analysis, it seems that the one that could best meet our expectations was the “incomplete” MVVM. We already had the model of the app isolated, so “only” we were missing the “-VVM” (more or less).

MVVM is short for Model-View-ViewModel, and was introduced in 2005 by John Gossman, Microsoft architect.

We have a winner?

Almost. It seemed that after this selection, everything would go faster. The reality is that you would be surprised by the MVVM variants and intermediate technologies used in iOS. Why? I repeat again, because each project has specific needs.

Returning to analyze the pattern, its uses, and the characteristics of our app, we essentially reached the following two conclusions:

  • Communication between ViewController and ViewModel was usually done with RxSwift. It is not a library that we used at the time.
  • Instances were the responsibility of the ViewControllers. We have a large number of screens, and we don’t want the controller to have as much responsibility for the navigation flow.

About RxSwift

Obviously, we could start using the library, but due to the type of requests we make to our server (unique and immediate), we decided that an observer added complexity and did not directly improve our architecture. As I mentioned, the logic of our app is made up of small groups belonging to unrelated business lines (laundry, beauty, fitness). So, despite being a large app, its parts are well differentiated, that is, there may be some direct coupling between the elements of the MVVM. RxSwift gave us a decoupling that was not necessary and made it difficult to trace the executions.

Solution: The ViewModel will communicate asynchronously with your ViewController using “delegated” protocols (yes, the usual ones).

About the navigations

As we have said, we have a large number of navigations to new screens. This navigation must be simple and controlled. For that, this logic cannot delegate on the ViewController. This has to behave like a mere data draftsman. We do not want you to know why or where you have to navigate, much less control sensitive app data.

Solution: In the search for the perfect pattern we find the term “Router” in VIPER, which, precisely, is responsible for performing all the functions we need to discharge the ViewController of responsibility.

We have a winner!

It seemed. Aware that we had not invented anything, we had found the MVVM best suited our app.

This is how our PURE SWIFT MODEL-VIEW-VIEWMODEL + ROUTER was born: Abbreviated as PSMVVMR??? 🤦🏻‍♂️

And is it done?

Of course not. Firstly, we define its main characteristics (apart from those that it already provides in the pattern itself). These would be the four most important points to keep in mind during its implementation. Our MVVM, first of all, should be:

  • Simple in understanding and use.
  • Robust and safe in use.
  • Generic in implementation of common functionalities.
  • Fast in creation capacity through templates.

With these clear points, it was time to get down to work and develop this new piece of architecture adapted to the project. But this will already be in a new part … Thank you! (very soon, part 2)

--

--