Architecting with VIPER — The paper of the View in a VIPER scene

I started to play with VIPER around 2 years ago. At first it was a little confusing what each element of that architecture was responsible for. And in fact distribute responsibilities is one of the main keys of VIPER. This post brings a little of my thoughts around the responsibilities of the View. Also, I decided to expose some practical questions, which means applying VIPER in real world situations. I find this type of approach more helpful than just abstract discussions.

User inputs

The view is the one responsible to deal with the user inputs. The simplest example that can be imagined is a tap in a button. Whenever that button is pressed, is the view that will be first notified. And then the view will inform the presenter about that event, without any filter, without any condition. The presenter is the one that will decide what will happen after.

Table view delegate

The view paper related to the user input sounds really simple, and for many different examples it really is. Things start getting blurred when more complex examples arrives. I've seen some people setting the presenter as the delegate of a UITableView. I have done it before myself. They do it in order to make the presenter to responds to actions such as didSelectRowAtIndexPath. I mean, at some point yes, the presenter is supposed to receive that action. But not now, after all, the view has to receive first all user inputs. So I guess the lesson is: let's try to make the view to receive all user events, and then let's propagate these event to the presenter. Even if there's a shorter way.

Long presses in cells

I saw other examples of misunderstanding of delegations before. I remember this one time that a project had a requirement of to intersect long presses on UICollectionView's cells. And there was a whole mess around that. Cells intersecting events and then reporting it to the presenter. Doesn't it sounds weird? Isn't the view that will have to be notified about this event first? There's a clear break in the VIPER attributions here.

A possible solution for long presses

I can imagine one possible solution to implement this requirement and still have the view being notified first about the user inputs. We could configure, on the view side, a long press for that UICollectionView. Whenever the long press is dispatched, we find the cell that was pressed according to the position of the event, and then we propagate this information to the presenter. We could create, let's say, a function called didLongPressCellAtIndexPath(_ indexPath:IndexPath) on the presenter side. This way the view is the one receiving the event first, and informing the presenter which cell was long pressed. Then the presenter do whatever it wants to do.

Display what is told by the Presenter

Now we're going to discuss the other attribution of the view. I think the best way to introduce you to the discussion is to base it on an example.

The weather app case

I may have a blurred case to introduce. Let’s say you have a UITableViewController for a weather app. The cell at section 0 and row 0 will change depending on the weather that day. If it's sunny it be a big cell with a sun image called SunnyCell. If it's raining now the cell presented will be the RainyCell. I have a couple questions to lead us to find the right delegation for each of our VIPER members, applied to this case.

  • Who’s going to instantiate/dequeue those cells?
  • Who’s going to fill those cells’ content?
  1. After having a reference for a cell, send that cell to the presenter to fill it's content (labels, images, etc).

Who will define which cells are going to be displayed when the view appears?

The weather that day is what will say which cell will be displayed at the top of our table view. The interactor is the one that will have a direct communication with the services offering this information. Let's imagine that this communication will be synchronous, just to make our problem less difficult. Interactors shouldn't contain any view logic. The presenter may have a function that will converter the weather that day in a cell type. Not the cell itself, just the type. The answer for the question would be: the presenter, with some help of the interactor, will define the cell type displayed on the top of the table view.

Who’s going to instantiate those cells?

We discussed before that this isn't a presenter task. Also the interactor doesn't know anything about UIKit. The wireframe is mostly related to navigation. The View will take care of instantiate/dequeue the cells of the table view. We are only facing a problem where the view is asking information to the presenter. It shouldn't. We'll have to work on that.

Who’s going to fill those cells content?

The presenter is the link between the information and the empty views. It will fill these cells whenever it has access to them.

The final architecture of the weather app

Every situation may require a different approach to solve problems. When dealing with VIPER and this weather app problem, there may appear dozen of different approaches in order to define the architecture of this "app". I will introduce you guys to one that I think will respect all VIPER definitions, but in real world maybe is not the perfect approach.

  1. Knowing that the view is ready, the presenter tells the interactor to start loading it's content, in our case, the weather information.
  2. After the content is loaded, the interactor notifies the presenter that the content was updated.
  3. The presenter gets the updated data and map it into cell types — that could be, for example, a list of enum cases.
  4. The presenter calls the view to update it's data, passing to it a list of cell types to be displayed.
  5. The view will receive the call to update the content. It will store the array of types somewhere and call the UITableView's reloadData. Now, whenever the cellForRow is called, the view knows exactly which type of cell is supposed to be displayed at a specific index path. And most important: The presenter is the one that told the view this information, with no need of the view to ask it.

A real world approach

Even though the example that I gave sounds a fair way to solve the problem we have been discussing, in real world it doesn't happen often. One thing I would possibly change here is the fact that the view keeps a list of cell types. This list could become big depending of the type of content displayed. Imagine for example the Facebook or Twitter feed. The list of cell types will get big soon.

Computer Engineer + iOS Engineer. I am interested in Swift, Kotlin, Firebase, Data Structures, ASO & On Solving Real World Problems.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store