Implementing VIPER Architecture Pattern for iOS

Understanding VIPER architecture’s logic and learn how to implement it in your app.

Mahdi Chtioui
7 min readSep 2, 2019

We use architectures in software development to organize our code into different layers, in order to make it cleaner, easier to test, to maintain and to write less boilerplate code.

As developers, we need to be familiar with different architectures, because sometimes we have to work on codes that are written by different developers that use different architectures. The least is that we have to know, is the principles of different architectures and how to implement them.

Normally when developing mobile apps, we use the most famous and popular architecture that is suggested by Apple, which is our beloved MVC.

MVC is not a bad architecture (there’s no such thing called bad architecture, we just have to choose the architecture that works best with our needs). It’s just when our app is a little bit large we will face a problem called “Massive ViewController”. As developers call it: Our ViewController will be responsible for almost everything (showing data, retrieving data from services, updating the UI, navigating to other ViewControllers …), basically, all our business logic will be implemented there. At this point using the MVP architecture will be a good idea since our View will be responsible only for updating the UI and all of our business logic will be moved to the presenter. The MVP architecture will solve our problem, but if the app keeps on growing. So is the presenter, and each time, there are a couple of new modules implemented into the app. The presenter then will contain a lot of code which will make it difficult to manage, harder to test and to maintain. And that’s where the VIPER architecture comes in.

If you ever want to develop Scalable applications, then VIPER architecture is the best choice for that matter.

What are the benefits of using VIPER?

VIPER offers a lot of benefits if used in the right way and for the right project:

  • Well suited for large and complex projects that grow over time by adding new features (Scalable Projects): Allow us to keep the project maintainable for the long term.
  • Simple and easy to understand code by other developers of the team. Makes identifying bugs and errors easy, since each layer has its own responsibility (Single Responsibility Principle): depending on the error, we can know which layer is responsible for that error.
  • Modular and well-organized project.
  • Adding or removing features is easy.
  • Reduce the load on controllers, which makes them light-weight.
  • UI logic is separated from Business logic.
  • Makes it easy to test and maintain the code.
  • Composition of the project is based on use cases.

Let’s start by introducing VIPER architecture

VIPER architecture it’s basically an implementation of a clean architecture for iOS applications, which is based on the Single Responsibility Principle: “Do one thing and do it well”.

Clean architecture divides the logic of our app into distinct layers. Each layer has its own responsibility.

Here’s an interesting post about Single Responsibility Principle.

VIPER will make our app modular. Each module will be composed of 5 layers that define the VIPER architecture (View, Interactor, Presenter, Entity and Router). Each layer has a distinct role or responsibility in the module.

Before we dive deep into VIPER’s layers and flow let’s start by having a clear vision about the implementation of this architecture.

The easiest way to picture an implementation of VIPER architecture is to put into mind that our ViewController will be structured into different elements. Meaning instead of having a ViewController, we’ll be having a View, Interactor, Presenter, Entity, and Router. As easy as that.

The best thing about VIPER is that it allows us to structure each module of our app into VIPER architecture. Each module will contain View, Interactor, Presenter, Entity, and Router, which makes the app cleaner, easier to test thanks to the separation of concerns it provides. Besides we don’t have to worry anymore about having a Massive ViewController or presenter (less boilerplate code).

To wrap up, our application will be composed of different modules. Each module has VIPER architecture implemented in it (View, Interactor, Presenter, Entity and Router).

Different layers of VIPER architecture

Let’s start by taking a look at each layer and understand its responsibility.

View

The view layer, which is basically the UIViewController and any other view type. This layer contains the UI logic (display, update, animate…) and responsible for intercepting the user’s action and send it to the presenter. Most importantly, it has no business logic.

Interactor

We can think of it as “The Network Manager”: responsible for retrieving data from the services (Network, database, sensors…) when requested by the presenter. The interactor is responsible for managing data from the model layer (note that Model is not part of the VIPER architecture, feel free to implement it or not, but for sure it will make our app more concise).

Presenter

I like to think of it as the motherboard, it connects all layers together. The presenter is the only layer that communicates with the view (The rest of layers communicates with the presenter). Basically, it’s the layer responsible for making decisions based on the user’s actions sent by The View.

Entity

Entities are simply our models that are used by the interactor. It’s best to put them outside of the VIPER modules at least, in my point of view, since these entities are usually shared in the entire system by the different modules.

Router

Someone calls it “Wireframe”. This layer is responsible for handling navigation logic: Pushing, Popping, Presenting UIViewControllers.

VIPER’s Flow and the relations between these layers

Now let’s see how these layers communicate between each other and the flow it follows.

VIPER Architecture Pattern

The view sends all the user interactions to the presenter to handle them and make the necessary UI changes. Depending on the interaction, the presenter may need some help from the interactor if it needs to retrieve data either remotely or locally or to perform some business logic using the entity. It also needs the help of the router in order to make any navigations to the other ViewControllers.

Take VIPER architecture to A WHOLE NEW LEVEL

I think it’s better to use a Model layer between the interactor and the entity. This Model layer is responsible for retrieving data when the interactor asks for it. It contains the entity and the managers of Remote and/or Local Database. These 2 managers are responsible for retrieving data using entities and send it to the Interactor when requested.

Our Interactor will act as the Data Manager, asks the managers (remote and local) for data when the presenter request these data. This solution will make our interactor light-weight and easier to write and understand.

But as I said earlier, it’s best to put the Model layer outside of the VIPER modules, since it’s used by the entire system with its different modules.

VIPER Architecture + Model

Implementing Example of VIPER architecture

To better understand this architecture, I prepared this demo example using VIPER. This demo example will show how to implement this architecture using Protocols for communication between its layers.

The demo is just a simple Posts app used from a dummy API online called “JSONPlaceholder” and here’s the link.

It’s simply an app that has 2 modules: one for listing posts in a UITableView from the dummy API and the other for viewing post details.

We will be using VIPER and a Model as explained in the previous section. Let’s get started.

Setup the Project Files and classes

There actually, a lot of Xcode templates out there that will do this for us (generate the files and folders). But for now, let’s do this manually since we’re still new to VIPER.

Project Composition (Xcode)
  • Model: contains our entities and services
  • Services: contains the class responsible for consuming the dummy API.
  • Modules: contains our modules: PostsListModule & PostDetailsModule.
  • Each Module: contains 5 folders (Remember that we placed Entity into Model): View, Presenter, Interactor, protocol, and Router.
  • Protocol: contains our protocols used to build communication between the layers.
  • The others are already explained earlier.

Build Our Model (Entity and Services)

Let’s start by our Entity, we will use the Object Mapper library for building the entity class “Post.swift”.

Post.swift

import Foundation
import ObjectMapper
struct Post : Mappable {
var userId : Int?
var id : Int?
var title : String?
var body : String?
init?(map: Map) { }

mutating func mapping(map: Map) {
userId <- map["userId"]
id <- map["id"]
title <- map["title"]
body <- map["body"]
}
}

Now let’s move to our PostService class which will be responsible for retrieving the list of posts from the API and mapped using our entity.

PostService.swift

Build the PostsListModule

Now that our model is ready, let’s start by building our PostsListModule.

PostsListProtocols.swift

PostsListInteractor.swift

PostsListRouter.swift

PostsListPresenter.swift

PostsListView.swift

I published the demo source code to GitHub.

Wrap up

VIPER is an architecture pattern that is based on the Single Responsibility Principle. Which divide our app into modules based on the use cases. Each module has 5 distinct layers, each has its own responsibility: View, Interactor, Presenter, Entity and Router.

VIPER is better used in large and scalable projects, it lets us manage complexity with less boilerplate code and we don’t have to worry about having a Massive ViewController.

--

--

Mahdi Chtioui

Mobile & Web Developer 💚 💙 Passionate by innovations, new technologies and design ❇️ GitHub: https://github.com/mahdichtioui