Creating an iOS Viper Module — Step by Step Guide

Emre Ergün
Trendyol Tech
Published in
8 min readMay 28, 2018

What is VIPER ? What is VIPER Module ? How should a module be assembled?

The Backstory

Recently, as iOS development team we have decided to migrate our project codebase from Objective-C to Swift, also we have discussed the use of a new architecture instead of keeping all stuff in MVC.

So, open XCode, select file and new project, choose swift as development language and start over again, right ? 🤔

Nope, sometimes things are not so that easy. In fact, product managers would not be happy if whole team left new upcoming features as well as sprint goals to work on migration process. Therefore, we had to do both swift migration and common sprint jobs in parallel to make everyone happy. Apple call it Mix and Match, details can be viewed from link below,

However this story is not about swift migration, also there are much better articles about it. If we focus on our decision about changing app architecture, what was the reason behind this ?Actually iOS project we have been working on was like a giant spaghetti in a pot that every developer add her/his own sauce to recipe for each new task.

So, which features should a good architecture provide?

  • Easily followable data flow.
  • Each object has a clear role separated from others.
  • Easy to test.

Truth is, our iOS project is lack of these features clearly.

Well, what are signs indicating there is a problem with app architecture ?

  • Massive view controllers with thousands of lines of code.
  • Getting lost while debugging.
  • Increasing number of global variables all along the app.
  • Nearly impossible to test.

Not surprisingly, these signs were defining our project. So, we have started to search for different architecture patterns used in iOS, with considering their pros and cons. After lots of reading, we have set a meeting to discuss with each other and make a final decision. At the end of the meeting, everyone seems to be satisfied with an architecture named VIPER to be our next.

What is VIPER ?

Viper is an architecture that divides a feature implementation into five distinct layer in one module. Each character of VIPER represents a different layer;

  • V: View
  • I: Interactor
  • P: Presenter
  • E: Entity
  • R: Router

Each layer has a distinct role in the module. In VIPER, I think implementing a feature like building a lego from different parts. Let’s take a look at each layer,

View

View is a dummy object receiving touch events most of the time. Instead of MVC’s massive view controller with thousands lines of codes, basically all service related codes and decision makings should not exist in it. For example, when a touch event was received from the user, view object should notify the presenter like “My dear presenter, a touch was received from user and I don’t know what I should do with it”

Presenter

I think presenter is the heart of the VIPER module. Only layer in the module that communicates with all other layers. Basically all decision makings should be handled in the presenter. After the decision, presenter has to communicate with the layer required. For example, after notified by view with touch event, presenter should decide what should be done next. Does screen need to update it’s UI ? Then tell view layer to update UI with given info. Should a data be fetch from remove server ? Then tell interactor to fetch it. Similarly, does app need to navigate to other screen ? Then tell router to navigate which screen it is.

Interactor

Interactor contains business logic and it’s mostly responsible from api calls. It builds request from parameters and creates objects by mapping response. After finishing service connection, it notifies presenter like “Hey presenter, these are puppies you are looking for” or “I’m sorry, I am not able to fetch your needs at this moment”. You get the idea.

Router

You need segue to another module ? Tell router which module it should be presented next and leave the rest to it. Router needs a UINavigationController instance to do such navigation stuff. Also I think that router should be responsible for showing alerts since UIAlertController is used with present method.

Entity

Plain data objects mainly driven by interactor. No more, no less.

To summarize, what a VIPER module should look like, take a look at the figure below;

Figure 1: Basic Viper Module Diagram

Meet the Best iOS Demo App Ever

Let’s convert something implemented in MVC to a viper module step by step. I created a very basic iOS app that consists of 3 screens which are Home, AddressList and AddressDetail. Home and AddressDetail are just dummy screens to provide integrity all around the app.

For example, let’s reimplement address list screen with VIPER. (Unit tests are skipped for now to make implementation short). Address list view controller simply presents addresses and if user clicks one of the addresses or add new address on the navigation bar, page navigates to address detail screen.

Before start, take a look at the AddressViewController

As you can see, making service calls, presenting popups, triggering segues etc all are handled in view controller. It may seem not a problem in this case, however believe me view controller will be getting bigger and bigger in the real world scenario in a similar situation. So, let’s implement it with VIPER.

Viper Module Implementation

First thing first, we should create layers, like;

  • AddressListView, aka AddressListViewController
  • AddressListPresenter
  • AddressListInteractor
  • AddressListRouter
  • Address as Entity

Of course all these layers should move under the folder AddressListModule.

Initial AddressList Module Folder Structure

Layer Interfaces

To make responsibilities clearer, each layer should apply a protocol to open themselves to other layers, from now on I will call it interface. For example, what does presenter want AddressListView to do ? Most probably it gives an array of address properties which are listed in the screen. Also grouping protocol methods with a comment according to who will use them would be better.

Before jump to implementation directly, let’s define interfaces of layers;

AddressListView Interface
AddressListPresenter Interface
AddressListRouter Interface
AddressListInteractor Interface

How did we write all these ? Answer is simple, thinking about responsibilities of each layer. Just be sure that each layer applies it’s own interface after defining them 🙃

After interfaces are done, define associated layer variables in each layer considering which layer it should communicate with. You may want to look at the Figure 1 at this moment.

Next we should think how we can create the module. Since different modules communicate between their routers, I think router should assemble the whole module. Since it is independent from module’s actual router instance, we can create a static module creation method in AddressListRouter;

Module Creation Static Method

Although static module creation method in router is just fine for me, I’d like to hear if you have a better idea.

Now, we can implement interface methods. Let’s check the AddressListViewController again after implementing methods;

AddressListView Implementation

Now you can see that view has no idea what is going on. Each time a user touch event is happened, lifecycle method is called, view tells what happened to presenter instead of doing something itself. Even it does not contain any data related with addresses, it just asks to presenter what will be displayed in the cells while reloading table view. So let’s look at the presenter then;

AddressListPresenter Implementation

As you can see that presenter determines what will happen next and invokes responsible layer. If fetching data is required, it tells to interactor, if the view should be updated, it makes it via view’s interface methods. Similarly, if a navigation stuff is required, it commands router to do it. However no UIKit related operation is allowed here. Also, when view is needed to address data, presenter gives only a part of the necessary properties will be displayed in the screen, it handled with giving tuple to view in the demo project.

Let’s look at the interactor;

AddressListInteractor Implementation

Interactor is just responsible from service calls in this module. It fetches address list using it’s service property whenever presenter requested. Also if an error occurs, interactor notifies the presenter with associated error message. Although there is no analytics event sending or fetching local data in this module, interactor is responsible from them. At last, router implementation can be seen below;

AddressListRouter Implementation

Whenever you present, pop or push something, you should know that it is router’s job. As you can see above, router provides that navigate another view controller, as well as presenting something includes popups. Again, since it is a demo project there is only one module in it, router should communicate with other modules in a real project in terms of navigation.

What about other stuff used in the module except layers ?

We have used custom cell named AddressListTableViewCell in the view layer to present address data. Also AddressListResponse and Address models are used by interactor layer. Since these files are associated with AddressList module, we should move these files under the module’s folder in the project navigator;

AddressList Module Folder Structure

Final Words

At the end of the story, we created an Viper module step by step. Although implementation of VIPER seems more work needed in first step, adding new capabilities to the layers is really easy thanks to the protocol oriented approach. Following data flow in the debugging is easy too, since each layer has a clear role. In addition to it, even view controller can be testable by using presenter when each life cycle method invoked and each user action happened.

However, it would be an overkill for the relatively small projects.

One last thing, if you are afraid number of layers that you should create for viper module, you may want to give a chance to script below, which is created by my teammate 😌

CIVIPERGenerator

Happy coding !

--

--