MVVM design pattern in Swift

MVVM design pattern

Reading Time: 3 minutes

MVVM design pattern (Model-View-ViewModel) is one of alternative design patterns in software development to MVC (Model-View-Controller) that solves common issues with MVC which results in smaller view controllers, better code separation and improved testability. But before diving into MVVM design pattern let’s talk a little about MVC or Model-View-Controller design pattern.
MVC design pattern (Model-View-Controller) is widely used design pattern where objects are assigned in one of 3 roles – model, view or controller. MVC also defines communication between these objects.

Model holds application data and is responsible for business logic (for example model can be a person, product, restaurant etc.). View presents data to user (but doesn’t communicate directly with model) and handles user interaction. Controller (ViewController) “glues” view and model, owns them and communicates with them (controller is responsible for fetching data from model and displaying that data with the views). If any data changes, model notifies the controller and controller updates the views. When user performs some action (for example taps on button) the view notifies controller. Controller then responds to that user action, for example it will fetch requested data or update the model.

MVC Model View Controller

Benefits of using this pattern are in reusability and code separation. So then you may be wondering what’s the problem with MVC pattern? Well in the end MVC implementation often looks like this. View knows little about the model (even it shouldn’t) and maybe even sometimes updates the model directly. And a lot of code you’re not sure where to put it (and you know it doesn’t belong in the model or view) ends in view controller. This results in very large and bloated view controllers. (that is a reason why MVC is also knows as massive view controllers) that does too much work (for example it handles user interaction, networking, data processing, data formatting etc), it’s hard to maintain and hard to test.

There are several alternatives to MVC that solves this problems like MVVM (Model-View-ViewModel), MVP (Model-View-Presenter) or VIPER (View-Interactor-Presenter-Entity-Router).

In this post we’ll cover one of the alternatives to MVC, called MVVM which stands for Model-View-ViewModel. So let’s dive in :).

MVVM design pattern (Model-View-ViewModel)

One of alternative design patterns in software development to MVC is MVVM design pattern (stands for Model-View-ViewModel) which popularity in iOS development community has risen in recent years. It solves common issues with MVC which results in smaller view controllers, better code separation and improved testability.

Actually MVVM is not that different from MVC. Main differences are that there is a new class ViewModel and that ViewController no longer communicates with Model. Model still represents the data but now communicates with ViewModel only. ViewModel then interacts with ViewController (and of course Model). View only communicates with ViewController (notifying it of user interaction) and ViewController interacts with View and ViewModel.

There is one more thing I would like to point out – in MVVM design pattern you can think about ViewController and View as one entity. ViewController doesn’t communicate with Model and is only responsible for handling View lifecycle events and for configuring UI.

MVVM design pattern

As you can see in image above ViewController owns the View and the ViewModel and ViewModel owns the Model. Model notifies the ViewModel which is then used to update ViewController and ViewController updates the View. Presentation logic is handled in ViewModel – for example if you need to format some data this is a place to do it. ViewModel doesn’t know anything about user interface (you shouldn’t even import UIKit in ViewModel).

I’ll update this post in the future with examples and link to project on GitHub.

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *