MVVM + FlowControllers -Part 1

Vinayak Srivastava
VMware 360
Published in
5 min readMay 27, 2021

Architecture strategy for iOS app development

Introduction

Mobile applications aim to provide customer solutions in various domains and can vary in the way they are created, tested and maintained. The architecture strategy for developing an application is the key factor contributing to the quality and competency of the overall project. Selecting the right architecture is possibly one of the key decision points in app development process that needs to be pinned right from the first sprint of project.

Particularly for iOS projects it was generally observed that MVC (model-view- controller) is the choice of many developers for a long time. But as our experience grew with this strategy, the rough edges and the inconsistencies began to emerge. It turns out the Cocoa touch framework forces us in many ways to gradually deviate from strictly following the MVC pattern. This is mostly due to the way Cocoa touch framework handles the view life cycle.

We will look into another architecture pattern MVVM (model-view-view model) along with FlowControllers and how they provide a more robust and clear strategy for the iOS projects. We will examine how this combination solves the inconsistencies and flaws of MVC for iOS.

MVC — Expectation vs. Reality

First let’s have a look at the MVC (mode-view-controller) architecture we all expect to see in development.

This is the broad representation of MVC we expect to see in iOS architecture. For the sake of brevity, MVC’s working can be quickly summarized as below:

  1. View receives the user input and informs the Controller.
  2. The Controller then fetches/updates the data necessary from the model and updates the View.
  3. Ideally Model, View and Controller are supposed to take responsibility of their assigned objectives and should not interfere or be aware about the existence of other components

Model — accessing and modifying Data

View — handle the GUI, in iOS all these classes are prefixed by ‘UI’

Controller — mediator between model and view

But Cocoa Touch framework offers a MVC pattern that has different flavor of the MVC we discussed above. With this framework, the MVC we get from an iOS project looks as shown below.

Cocoa Touch does tight coupling of View and Controller together while exposing the View’s lifecycle to ViewController. This of course is a by-product of the design where UIView is representing View and UIViewController is representing Controller. With this we can see a couple of things are off from what we expected.

Moreover, this approach fails to conform to some essential design principles in an architecture namely: ‘Separation of Concerns’ and ‘Single Responsibility’ principles. Separation of Concerns states that each section should be designated with a separate concern, which is essential to keep the code modular. Single Responsibility states that a class should have one and only one reason to change, meaning that a class should have only one job.

Model is pretty much still following these principles, but with the tight coupling of UIView and UIViewController, this is hard to achieve here. This gets muddier and more confusing when we introduce networking and business logic into the mix.

Unit testing can become extremely cumbersome as business logic and networking almost always get inadvertently coupled with View’s lifecycle.

The Cocoa Touch framework forces us in many ways to gradually deviate from strictly following the MVC pattern and SOLID principles. It should be noted that the MVC started off as a good strategy for web applications and the same can’t be expected to work efficiently in mobile app.

MVVM (Model-View-ViewModel)

MVVM introduces three components:

  1. Model — for accessing and modifying Data
  2. View — for UI only. No controller work involved here
  3. ViewModel — for representing ‘state’ of view, independent of UIKit

In order to incorporate MVVM in iOS we need to adapt to the understanding of treating UIView and UIViewController together as View.

(UIView + UIViewController) → Represents View component. This makes even more sense now, as we know how the Cocoa Touch binds the UIView’s lifecycle with that of UIViewController. With this understanding, MVVM for iOS can be described as in below diagram:

Note the ownership in above figure. View owns the ViewModel and ViewModel owns the Model. Now there is no tight coupling between all these components.

  1. View binds the user action with the ViewModel. UIView, UIViewController and its subclasses are treated as View.
  2. ViewModel represents the state of the View and handles the business logic. This makes the View change itself accordingly.
  3. ViewModel owns and updates the Model, while Model interacts with the Data layer and notifies ViewModel of the changes.

Unit testing this is now simpler as ViewModel can now be tested for the business logic independent of the View’s lifecycle.

Example for MVVM

Let’s consider a simple app below to see how MVVM would be implemented.

In above figure you have a simple UI screen with two button “Day” and “Night” and a Text Field to show greeting message. The app should update the greeting message based on the day/night button tapped on the screen.

With the MVVM pattern, this can be implemented in following steps:

  • UIViewController can take up the task of showing UI screen with the button and greeting text message. It owns an instance of ViewModel class.
  • ViewModel owns an instance of Model class and has a delegate for GreetingProtocol.
  • On tap on Day/Night button, the event is sent to ViewController which informs ViewModel by calling btnAction() method.
  • ViewModel in turns ask Model to fetch the corresponding message for day/night from its Database. With the use of delegate, the ViewModel then propagates message back to the View.
  • ViewController can now update this message and show it on the UI screen.

Note that using Protocol here is one of the solutions to keep the binding between View and ViewModel for their communication, without breaking the ownership in MVVM. This could have been achieved in any different way also as long as the ownership chain is maintained.

Part 2 : Continue reading to the part 2 of this article, where FlowControllers and it’s working with MVVM will be discussed.

--

--