What Are the Responsibilities of a View Controller

What Are the Responsibilities of a View Controller

If you are familiar with the Model-View-Controller pattern, then you know that it splits an application up into three components or layers:

  • the view layer
  • the model layer
  • and the controller layer

The Model-View-Controller Pattern On iOS

Model Layer

The model layer is in charge of the application's business logic. It manages the state of the application. This also includes reading and writing data, persisting application state, and it may even include tasks related to data management, such as networking and data validation.

View Layer

The view layer has two important tasks:

  • presenting data to the user
  • and handling user interaction

A core principle of the Model-View-Controller pattern is the view layer's ignorance with respect to the model layer. Views are dumb objects. They only know how to present data to the user. They don't know or understand what they are presenting.

Controller Layer

The view and model layers are glued together by one or several controllers. In iOS applications, that glue is a view controller, an instance of a UIViewController subclass. In macOS applications, controllers are most often instances of a NSWindowController subclass.

A controller knows about the view layer as well as the model layer. This usually results in tight coupling, making controllers the least reusable component of an application based on the Model-View-Controller pattern. The view and model layers don't know about the controller. The controller owns the views and the models it interacts with.

Massive View Controller Symptom

If you have spent any amount of time reading books or tutorials about iOS or macOS development, then you have probably come across people complaining about MVC. Why is that? What is wrong with the Model-View-Controller pattern?

One of the key benefits of the Model-View-Controller pattern is a clear separation of concerns or responsibilities. It makes your life as a developer easier. Projects are easier to architect and structure. But that is only part of the story. A lot of the code you write doesn't belong in the view or model layer. No problem. Dump it in the controller. Problem solved. Right? Not really.

Data formatting is a common task. Imagine that you are developing an invoicing application. Each invoice has a creation date. Depending on the locale of the user, the date of an invoice needs to be formatted differently.

Data formatting and transformation is a task that is often delegated to the controller.

The creation date of an invoice is stored in the model layer and the view displays the formatted date. That is obvious. But who is responsible for formatting the date? The model? Maybe. The view? Remember that the view should not need to understand what it is presenting to the user. But why should the model be responsible for a task that is related to the user interface?

Wait a minute. What about our good old controller? Sure. Dump it in the controller. After thousands of lines of code, you end up with a bunch of massive view controllers, ready to burst and impossible to test. Isn't the Model-View-Controller pattern the best thing ever?

Model-View-ViewModel to the Rescue

There are several alternative patterns that can help solve this problem. Model-View-ViewModel is a pattern that is gaining traction in the Swift community. It introduces a fourth component or layer to the application architecture, the view model.

The Model-View-ViewModel pattern introduces a fourth component or layer to the application architecture.

The view model sits in between the model and controller layer. It is the view model that owns the model, not the controller.

The view controller is no longer responsible for transforming the raw values of the model and it doesn’t even know about the model.

Let me show you what happens when the view controller needs to display a piece data in the view it manages. The view controller asks its view model for data. The view model asks the model it manages for the raw value, a timestamp for example. It applies the necessary transformations to the raw value and returns a value the view controller can immediately display to the user in its view.

The view controller is no longer responsible for transforming the raw values of the model and it doesn’t even know about the model. That is an important difference with the Model-View-Controller pattern.

Mastering Model-View-ViewModel With Swift

In Mastering Model-View-ViewModel With Swift, you learn everything you need to know about the Model-View-ViewModel pattern to put the controllers of your projects on a diet. The results are pretty dramatic. Controllers are skinnier, lightweight, and focused. They present data to the user and respond to user interaction. That is what controllers are meant to do.

The view models you create solve a specific problem, which makes them easy to create and manage. Because they are not tied to the user interface, view models are incredibly easy to test. The testability of your projects increases significantly with the Model-View-ViewModel pattern.

Are you ready for the challenge? Check out Mastering Model-View-ViewModel With Swift.