This post is part 1 of the tutorial.
→ Check part 2 to see VIPER in action.
→ Check part 3 to learn how to do unit tests with VIPER.
VIPER is a design pattern mostly used on the development of iOS applications. It’s an alternative to other design patterns like MVC or MVVM and offers a good layer of abstraction resulting in a more scalable and testable code. It also has its disadvantages, but I’ll talk about them in a minute.
Besides VIPER, CoreData will also be used to persist information between sessions on the application’s cache. It’s very simple and easy to use allowing us to store information on a local database without much configuration.
Our application will be a simple todo list with CRUD operations, giving users the ability to create todos, mark them as completed and delete them.
The VIPER Architecture
Just like MVC or MVVM, VIPER is a design pattern created to facilitate the development by creating layers of abstraction and isolation of concerns, creating a cleaner code, and bringing more maintainability further down the road. VIPER goes an extra step into achieving the perfect single responsibility principle, stating that each component should have responsibility for a single functionality.
VIPER is an acronym for View-Interactor-Presenter-Entity-Router. Each functionality or module must be defined by these five components.
View
It’s what the user sees, the view that represents a functionality. In some cases, a single functionality can have multiple views, for example, an onboarding flow with multiple steps. The Router is responsible for transitioning between those views, and they will all use the same Interactor, Presenter, Entity, and Router.
Interactor
Responsible for handling logic after receiving orders from the Presenter. Returns the result through a delegate on the Presenter.
Presenter
It’s the crossroad that connects all the other components. Receives user actions from the View, sends and receives data from the Interactor, and route to other screens using the Router.
Entity
It’s the information and data used on the functionality. In our case, it will be CoreData since our information will be stored there.
Router
Controls the navigation flow between screens using UINavigationControllers or between modules by changing the root ViewController of the current Window.
Comparison with MVVM
A design pattern that offers a similar level of abstraction is MVVM (Model-View-ViewModel). Between both patterns, we can identify the similarities, for example:
- The View on MVVM is the View on VIPER;
- The Model on MVVM is the Entity on VIPER;
- The ViewModel is represented by the rest of the VIPER components (Interactor, Presenter, and Router).
From this simple analysis, we immediately understand that VIPER offers a bigger abstraction to handle business logic. While MVVM uses the ViewModel to handle logical operation, interacts with the view, and performs routing, VIPER has a separate component for each one. This is the single responsibility principle in practice that VIPER defends.
Having a separate component for everything has some downsides since it will generate more core just to keep everything connected, effectively increasing the development time. Further down the road, this time will be gained, for example, when doing Unit Tests.
VIPER — When and Why
By using VIPER the developer must understand that he will lose some time to implement a good foundation for each module or functionality, making use of VIPER’s pattern. This will be a tedious and time-consuming task. For that reason, many developers tend to use MVVM since it offers a similar abstraction but with less effort.
Nonetheless, its common belief that in the long term VIPER is a better solution. Still, this is debatable and depends on multiple factors that will influence our approach to the project. If you’re aiming for an MVP or you have a relatively short timeframe, you should go with MVVM as it’s quicker to start up a project with it. If your project is complex and expected to be well thought and developed along the way, VIPER offers a better approach to accomplish that.
With the above in consideration, it’s safe to say that some of the advantages of VIPER are:
- More abstraction and therefore more scalability options in the future.
- A tighter architecture that is more reliable and less prone to error.
- Although the initial stages of development can be slow, after understanding the flow it’s as easy and fast as implementing any other architecture.
- Easier for developers to understand where is what because of the single responsibility principle.
On the other hand, VIPER also has some disadvantages:
- Generates a lot of boilerplate code, making the initial development phase slower. It’s very dependent on protocols and delegates to transmit data and actions between components.
- Harder to fully understand how it works until it’s applied in a real-case scenario.
It’s up to the development team, in coordination with the management team to decide what is the best approach for not only the project, but also the expertise level of the developers. VIPER is not suitable for Junior level developers, as some configurations might require more knowledge of the Swift programming language.
After going through the theory behind VIPER, it’s time for us to jump into action and learn more about the practical side of it! Jump to part 2 to start implementing VIPER or go right to part 3 if unit tests are what you are looking for!
Also, don’t forget to follow Pixelmatters on Medium, Twitter, Facebook, LinkedIn, and Instagram.