Introduction to the MVVM Design Pattern with Swift

Shan
6 min readSep 24, 2018

A better architecture for your project.

Introduction

I write Swift codes about two years, and usually I build iOS projects with the MVC structure. Using MVC in iOS is simple and intuitive because Apple provides the ViewController class. At first, the ViewController is clean and thin. Maintaining things in ViewController takes no burden. As the project getting bigger and bigger, codes in the ViewController would be a mess, and it is hard to trace and maintain the codes inside the ViewController.

Recently I got a chance to refactor a project. To make the project can be maintained more easily in the future, I decide to try the MVVM structure. After finishing the refactor, I found that the MVVM helps a lot to clean the codes inside the ViewController.

In this article, I will use a simple project to show you how you can build an iOS project with the MVVM.

Note: I assume that you have basic understanding of Swift, like MVC, parsing JSON, closure, protocol and delegate. If not, please let me know. Thanks.

The MVVM Diagram

An Animation to Show the Components of MVVM

MVVM is an abbreviation for Model, View Model and View. The View here includes both the ViewController and View components in the MVC.

In MVC, Controller is the bridge between the View and Model. Controller manipulates the Model to generate the necessary data, and notify the View to show that data. The responsibilities for each components in MVC seem clear and good to write the codes. But actually it is not like that in reality because the Controller has to maintain too many things.

These are things that a ViewController in MVC would interact with:

  1. Respond to user interaction.
  2. Maintain the View transition.
  3. Maintain the instances of Models.
  4. Maintain some logics.

Maintaining codes about View displaying and business logics is the reason that a ViewController is hard to maintained and tested. So, there is one more component in MVVM to decrease the responsibilities of ViewController.

The ViewModel.

The MVVM Structure

The job of ViewModel is to prepare the necessary data for ViewController. So, whenever a ViewController needs some kind of data, all the things that ViewController needs to do is asking ViewModel for that data.

The Demo of using MVVM

What we will build

In this article, the goal of demo iOS project is to retrieve some data from the Data.Taipei and show that data with a UITableView. The complete project will be like this:

A Tableview to Show the Information of Elementary Schools in Taipei

You can visit here to know how you can access all the public information of elementary schools in Taipei. Basically we will use the following URL to retrieve the data:

http://data.taipei/opendata/datalist/apiAccess?scope=resourceAquire&rid=24c9f8fe-88db-4a6e-895c-498fbc94df94.

After sending request to that URL, we will get some JSON data. The data looks like this:

The Structure of the Elementary School Data

All we need here is the name and address for each elementary school. We can access the name by the key “o_tlc_agency_name”, and access the address by the key “o_tlc_agency_address”.

Now we know what to build and where we can get the data. Let’s write some codes!

A Class to Represent the Elementary School

We will use this class to represent an elementary school object. And we will use retrieved JSON data to initialize it.

A Help Class to Retrieve the Data

Overview of Help Class

Create a help class DataManager. This class will handle things about retrieving remote data.

The getData(dataURLString:completion:) will send the request to the passed URL, and return an optional data object by the completion closure.

The decodeData(data:) will decode the passed data object, and return an optional array of ElementarySchool.

The retrieveDataWith(urlString:completion:) will call getData(dataURLString:completion:) and decodeData(data:) to do those tasks, and return an optional array of ElementarySchool by the completion closure.

The detailed implementations of DataManager are as follows

The ViewModel Class

Overview of ViewModel.

The SchoolViewModel class will be the ViewModel for the ViewController. The responsibility of SchoolViewModel is that it will prepare the necessary data for ViewController, and it will notify ViewController when the data is ready.

Below are the descriptions for each comment from comment 1 to comment 7.

// 1.: The cellViewModels is an array of CellViewModel, which is maintained by the ViewModel to store the data that will be shown in the rows of UITableView.

// 2.: The dataManager is an instance of help class. ViewModel will use this instance to get data.

// 3.: The notificationDelegate is a delegate that will be notified when the data in the ViewModel is ready to be shown.

// 4.: The fetchDataWith(urlString:) is a function used by the ViewModel to get the data.

// 5.: The getCellCount() is a function that can be called by the ViewController to know how many rows it should show in the UITableView.

// 6.: The getCellName() is a function that can be called by the ViewController to know what the school name is to show in the UITableViewCell.

// 7.: The getCellAddress() is a function that can be called by the ViewController to know what the school address is to show in the UITableViewCell.

The detailed implementations of SchoolViewModel are as follows

We notify the delegate that data is ready in line 14.

The ViewController

Overview of SchoolViewController

The SchoolViewController class will be the ViewController of this demo project. It has a UITableView schoolList to show information of schools. Also, it maintains an instance of ViewModel to prepare the data.

The SchoolViewController conforms to the UITableViewDataSource to tell the UITableView how to present the data. In addition, the SchoolViewController conforms to the SchoolDataNotification protocol to be notified by the ViewModel when the data is ready.

The SchoolDataNotification protocol is defined as follows

.

The detailed implementations of SchoolViewController are as follows

In the tableView(_ :cellForRowAt:), all we need to do is asking the ViewModel for the corresponding data.

Conclusion

Using a ViewModel to prepare the data is the core idea of MVVM. All the things that the ViewController has to do is asking the ViewModel for the data to be shown. Now it is more easily to maintained the ViewController because almost all the business logics are handled in the ViewModel.

The complete project can be found in this GitHub repository.

Please click the claps button or leave some comments if this article helps you. Thanks.

--

--

Shan

Engineer @ Perfect Corp. Focused on iOS development, drone and graphic design.