Before your next project, learn MVVM

I am not an expert in iOS development. I recently started to develop applications for multiple industries in Swift after learning for a month. I did like every beginner and opened Apple documentation and followed their guidelines. The recommended pattern by Apple is the MVC model. I started building my first apps following the classic principles of Model View Controller that we all know and cherish. On paper, the MVC model in iOS development is no different than the one we used for years. Unfortunately for me, I always were interested in Software architectures, clean codes and beautiful pieces of software and as such the combination of iOS and MVC were a pain to work with.

The Massive View Controller 😓

“Close-up of colorful lines of code on a computer screen” by Markus Spiske on Unsplash

Model View ViewModel 🚀

To illustrate this, let’s imagine a stupid view that print the current date. We can start by designing the ViewModel:

Simple ViewModel example

Here, the ViewModel exposes one variable and one method. The fetchDate() method will fetch the current date and assign it a private variable. This variable will call an optional public method updateDate each time it is set. This method is a public variable and a such can be set by the View:

Simple View

After instantiating the ViewModel, the View will simply attach its closure(s) to the exposed variable of its ViewModel and then trigger the fetch. The setupView method will populate the view with initial content if you require it. When the fetch complete with success and the callback is called on the fetchDateFromApi function, updateDateClosure will be called and will update the label. All of this asynchronously and easily maintainable.

The routing situation 🚥

A basic but clear router implementation

The viewController init method is a convenience init to not have to look for the corresponding Storyboard. The Enum and Protocol are just here for clarity purposes. But this allow us to simply reference this router in our files:

Adding the router to the previous classes

And we can the easily navigate through pages with route?.navigate(.home).

Caveats ⚠️

  • The closure and asynchronous nature of the pattern makes it harder to debug. The stack quickly become cluttered by the calls to each method.
  • Be aware of the strong references to avoid memory leaks in closures and class variables. For example, if you forget the weak keyword in the router reference to the view, they will each reference each other with a strong reference and will never be deallocated from memory.

I cannot overstate how much a difference a good architecture can do. With a good architecture, implementing features become easy and fast. Whatever you favorite architecture pattern, before your next project, give a try to MVVM 👍. If you are interested in the subject, you can also read about Viper and MVVMC

🍺 Beer Homebrewer, Software engineer and tech aficionado