MyPage is a personalized page based on your interests.The page is customized to help you to find content that matters you the most.


I'm not curious

Swift Tutorial: An Introduction to the MVVM Design Pattern

Published on 06 February 17
1376
0
1

So you’re starting a new iOS project, you received from the designer all the needed .pdfand.sketch documents, and you already have a vision about how you’ll build this new app.

You start transferring UI screens from the designer’s sketches intoyour ViewController.swift,.xib and .storyboard files.

UITextField here, UITableView there, a few more UILabels and a pinch of UIButtons. IBOutlets and IBActions are also included. All good, we are still in the UI zone.

However, it’s time to do something with all these UI elements; UIButtons will receive finger touches, UILabels and UITableViews will need someone to tell them what to display and in what format.

Suddenly, you have more than 3,000 lines of code.
8
Swift Tutorial: An Introduction to the MVVM Design Pattern - Image 1

You ended up with a lot of spaghetti code.

The first step to resolve this is to apply the Model-View-Controller (MVC) design pattern. However, this pattern has its own issues. There comes the Model-View-ViewModel (MVVM) design pattern that saves the day.

1
Dealing with Spaghetti Code

In no time, your starting ViewController has become too smart and too massive.

Networking code, data parsing code, data adjustments code for the UI presentation, app state notifications, UI state changes. All that code imprisoned inside if-ology of a single file that cannot be reused and would only fit in this project.

Your ViewController code has become the infamous spaghetti code.

How did that happen?

The likely reason is something like this:

You were in a rush to see how the back-end data was behaving inside the UITableView, so you put a few lines of networking code inside a temp method of the ViewController just to fetch that .json from the network. Next, you needed to process the data inside that .json, so you wrote yet another temp method to accomplish that. Or, even worse, you did that inside the same method.

The ViewController kept growing when the user authorization code came along. Then data formats started to change, UI evolved and needed some radical changes, and you just kept adding more ifs into an already massive if-ology.

But, how come the UIViewController is what got out of hand?

The UIViewController is the logical place to start working on your UI code. It represents the physical screen you’re seeing while using any app with your iOS device. Even Apple uses UIViewControllers in its main system app when it switches between different apps and its animated UIs.

Apple bases its UI abstraction inside theUIViewController, since it is at the core of the iOS UI code and part of the MVC design pattern.
13
Upgrading the MVC Design Pattern
Swift Tutorial: An Introduction to the MVVM Design Pattern - Image 2

In the MVC design pattern, View is supposed to be inactive and only displays prepared data on demand.

Controller should work on the Model data to prepare it for the Views, which then display that data.

View is also responsible for notifying the Controller about any actions, such as user touches.

As mentioned, UIViewController is usually the starting point in building a UI screen. Notice that in its name, it contains both the view and the controller. This means that it controls the view. It doesn’t mean that both controller and view code should go inside.

This mixture of view and controller code often happens when you move IBOutlets of little subviews inside the UIViewController, and manipulate on those subviews directly from the UIViewController.Instead you should’ve wrapped that code inside of a custom UIView subclass.

Easy to see that this could lead to View and Controller code paths getting crossed.
7
MVVM to the Rescue

This is where the MVVM pattern comes in handy.

SinceUIViewControlleris supposed to be a Controller in the MVC pattern, and it’s already doing a lot with the Views, we can merge them into the View of our new pattern - MVVM.
1
Swift Tutorial: An Introduction to the MVVM Design Pattern - Image 3

In the MVVM design pattern, Model is the same as in MVC pattern. It represents simple data.

View is represented by the UIVieworUIViewController objects, accompanied withtheir .xiband.storyboard files, which should only display prepared data. (We don’t want to have NSDateFormatter code, for example, inside the View.)

Only a simple, formatted string that comes from the ViewModel.

ViewModel hides all asynchronous networking code, data preparation code for visual presentation, and code listening for Model changes. All of these are hidden behind a well-defined API modeled to fit this particular View.

One of the benefits of using MVVM is testing. Since ViewModel is pure NSObject (or struct for example), and it’s not coupled with the UIKit code, you can test it more easily in your unit tests without it affecting the UI code.

Now, the View (UIViewController/UIView) has become much simpler while ViewModel acts as the glue between the Model and View.
9
Applying MVVM in Swift
Swift Tutorial: An Introduction to the MVVM Design Pattern - Image 4

To show you MVVM in action, you can download and examine the example Xcode project created for this tutorial here. This project uses Swift 3 and Xcode 8.1.

There are two versions of the project: Starter and Finished.

The Finished version is a completed mini application, where Starter is the same project but without the methods and objects implemented.

First, I suggest you download the Starter project, and follow this tutorial. If you need a quick reference of the project for later, download the Finished project.
1
Tutorial Project Introduction
The tutorial project is a basketball application for the tracking of player actions during the game.
Swift Tutorial: An Introduction to the MVVM Design Pattern - Image 5

It’s used for the quick tracking of user moves and of the overall score in a pickup game.

Two teams play until the score of 15 (with at least a two-point difference) is reached. Each player can score one point to two points, and each player can assist, rebound, and foul.

Project hierarchy looks like this:
Swift Tutorial: An Introduction to the MVVM Design Pattern - Image 6

Model

  • Game.swift
    • Contains game logic, tracks overall score, tracks each player’s moves.
  • Team.swift
    • Contains team name and players list (three players in each team).
  • Player.swift
    • A single player with a name.

View

  • HomeViewController.swift
    • Root view controller, which presents the GameScoreboardEditorViewController
  • GameScoreboardEditorViewController.swift
    • Supplemented with Interface Builder view in Main.storyboard.
    • Screen of interest for this tutorial.
  • PlayerScoreboardMoveEditorView.swift
    • Supplemented with Interface Builder view in PlayerScoreboardMoveEditorView.xib
    • Subview of the above view, also uses MVVM design pattern.
3

ViewModel

  • ViewModel group is empty, this is what you will be building in this tutorial.

The downloaded Xcode project already contains placeholders for the View objects (UIView and UIViewController). The project also contains some custom-made objects made to demo one of the ways on how to provide data to the ViewModel objects (Services group).

The Extensions group contains useful extensions for the UI code that are not in the scope of this tutorial and are self-explanatory.

If you run the app at this point, it will show the finished UI, but nothing happens, when a user presses the buttons.

This is because you’ve only created views andIBActionswithout connecting them to the app logic and without filling UI elements with the data from the model (from theGameobject, as we will learn later).

4
So you’re starting a new iOS project, you received from the designer all the .pdf.sketch, and you already have a vision about how you’ll build this new app.

You start transferring UI screens from the designer’s sketches ViewController.swift.xib .storyboard.

UITextField here, UITableView there, a few UILabels a pinch of UIButtons. IBOutlets IBActions also included. All good, we are still in the UI zone.

However, it’s time to do something with all these UI elements; UIButtons will receive finger touches, UILabels UITableViews need someone to tell them what to display and in what format.

Suddenly, you have more than 3,000 lines of code.

this is to apply the Model-View-Controller (MVC) design pattern. However, this pattern has its own issues. There comes the Model-View-ViewModel (MVVM) design pattern that saves the day.

ViewController become too smart and too massive.

Networking code, data parsing code, data adjustments code for the UI presentation, app state notifications, UI state changes. All that code imprisoned inside if-ology of a single file that cannot be reused and would only fit in this project.

ViewController has become the infamous spaghetti code.

How did that happen?

The likely reason is something like this:

You were in a rush to see how the back-end data was behaving inside UITableView so you put a few lines of networking code inside a temp method of ViewController to fetch .json the network. Next, you needed to process the data inside .json so you wrote yet another temp method to accomplish that. Or, even worse, you did that inside the same method.

ViewController growing when the user authorization code came along. Then data formats started to change, UI evolved and needed some radical changes, and you just kept adding if into an already massive if-ology.

But, how come UIViewController what got out of hand?

UIViewController the logical place to start working on your UI code. It represents the physical screen you’re seeing while using any app with your iOS device. Even Apple UIViewControllers its main system app when it switches between different apps and its animated UIs.

Apple bases its UI abstraction inside UIViewController since it is at the core of the iOS UI code and part of the MVC design pattern.

should work on the Model data to prepare it for the Views, which then display that data.

is also responsible for notifying the Controller about any actions, such as user touches.

As mentioned, UIViewController is usually the starting point in building a UI screen. Notice that in its name, it contains both the view and the controller. This means that it controls the view. It doesn’t mean that both controller and view code should go inside.

This mixture of view and controller code often happens when you IBOutlets little subviews inside UIViewController and manipulate on those subviews directly from UIViewController you should’ve wrapped that code inside of a UIView.

Easy to see that this could lead to View and Controller code paths getting crossed.

UIViewController supposed to be a Controller in the MVC pattern, and it’s already doing a lot with the Views, we can merge them into the View of our new pattern - MVVM.

is represented by UIViewUIViewController, accompanied .xib.storyboard, which should only display prepared data. (We don’t want to have NSDateFormatter , for example, inside the View.)

Only a simple, formatted string that comes from the ViewModel.

ViewModel hides all asynchronous networking code, data preparation code for visual presentation, and code listening for Model changes. All of these are hidden behind a well-defined API modeled to fit this particular View.

One of the benefits of using MVVM is testing. Since ViewModel is pure NSObject (struct example), and it’s not coupled with UIKit, you can test it more easily in your unit tests without it affecting the UI code.

Now, the View (UIViewController/UIView) has become much simpler while ViewModel acts as the glue between the Model and View.

and follow this tutorial. If you need a quick reference of the project for later, download the Finished project.

Main.storyboard
  • of interest for this tutorial.
  • PlayerScoreboardMoveEditorView.swift
    • Supplemented with Interface Builder view in PlayerScoreboardMoveEditorView.xib
    • Subview of the above also uses MVVM design pattern.


  • is empty, this is what you will be building in this tutorial.The downloaded Xcode project already contains placeholders for the View objects (UIView and UIViewController). The project also contains some custom-made objects made to demo one of the ways on how to provide data to the ViewModel objects (Services group).

    Extensions contains useful extensions for the UI code that are not in the scope of this tutorial and are self-explanatory.

    If you run the app at this point, it will show the finished UI, but nothing happens, when a user presses the buttons.

    This is because you’ve only created views IBActions connecting them to the app logic and without filling UI elements with the data from the model (from Game, as we will learn later).

    Article via Toptal.

    4

    This blog is listed under Development & Implementations Community

    Related Posts:
    Post a Comment

    Please notify me the replies via email.

    Important:
    • We hope the conversations that take place on MyTechLogy.com will be constructive and thought-provoking.
    • To ensure the quality of the discussion, our moderators may review/edit the comments for clarity and relevance.
    • Comments that are promotional, mean-spirited, or off-topic may be deleted per the moderators' judgment.
    You may also be interested in
     
    Awards & Accolades for MyTechLogy
    Winner of
    REDHERRING
    Top 100 Asia
    Finalist at SiTF Awards 2014 under the category Best Social & Community Product
    Finalist at HR Vendor of the Year 2015 Awards under the category Best Learning Management System
    Finalist at HR Vendor of the Year 2015 Awards under the category Best Talent Management Software
    Hidden Image Url

    Back to Top