The call it an implementation of the clean architecture to iOS Apps. Here is a discussion about how VIPER can work.
- Some understanding of OO terminology and practices
View: Use the data sent by the presenter, and display it. Can also pass touch events, but will simply notify the presenter of this, where the work to process the touch takes place. In practice the view sets up the presenter (owns it), and sends messages to the same.
Interactor: Bidirectionally interacts with the presenter to receive inputs, fetch data, perform complex calculations, the results of which are displayed to the user through the interactor. The Interactor can communicate with a DataManager (the component responsible for fetching data from the network), based on the translated user input fed by the Interactor. In practice the Interactor can get data from a webservice.
Presenter: Interacts directly with the view and the interactor. Responsible for taking user inputs from the view, and transferring them to the interactor. Presenter changes the type of the data, if the Interactor requires the data in a specific format. In practice the modules communicate through the presenters.
Entity: The model representation of the data.
Router: Routes the App to the appropriate screen. The router has to have a direct reference to the viewcontroller, with the presenter acting as an intermediary between view and router.
Provide a clear data flow, with objects that have a distinct role and is easy to test.
—To make the structure modular
— To build applications on the Single responsibility principle
— To reduce the load and dependency on controllers
— To build the App on a behaviour basis
Communication between objects can be convoluted and complicated. Without care, modules can become too large and do too many things. This violates the single responsibility principle!
The interactor gets some data from an API, and passes the data to the presenter which then passes the formatted data to the view.
Here is an in-depth bullet-point list for the VIPER architecture.
View (view controller)
- creates router
- Performs segues and therefore looks after views
- creates presenter
- Binds the presenter to the view
- creates interactor
- binds the interactor to view
- binds the interactor and the presenter
- When data is fetched, informs the presenter through closures
- has functions that are called by the interactor, and informs the view controller through the delegate pattern.
- Performs anything to make the data in a format that the view can easily display
The long story short version:
- The builder holds no one.
- The router keeps a weak reference of the view and the presenter.
- The presenter holds the router and the interactor strongly
- The interactor keeps a weak refernece of the presenter
- The view keeps a strong refernece of the presenter
- UIKit holds the views.
Supports SOLID principles (Single responsibility, Open-closed, Liskov substitution, Interface segregation, Dependency Inversion). Which will make your life easier…
Great for Test Driven Development (TDD), where you write the tests before the application code. This is partly because the architecture helps you to separate your code, and make good predictions about where code should go.
Because of these disadvantages it can actually mean that it is slower to ship code. However, the code is likely to be better and more maintainable.
Modules are loosly coupled so it is easy to test the modules seperately.
Is good for large teams because the modules are separate. This means that there are fewer merge conflicts and issues.
Conformity of structure means that it is faster to read other people’s code, and the individual files are smaller than those in MVC meaning the logic is clearer and the overall stability and flexibility of the project is higher. This conformity means that cross-platform code reviews with Android teams are even possible!
Modules should communicate by the presenters. One way to handle this is ViperMcFlurry to assist with intermodule data transfer, as it is complex with method swizzling engaged (but obviously this is quite tricky).
Even UBER (one of the more famous users of the VIPER architecture) don’t use all of the files in VIPER, and use RIBS instead (router, Interactor and builder)!
VIPER can be seen as overengineered. We need 4 classes to make a very simple app to pass data from a API. All of these files are also recreated with testing, and it makes it very tricky and adds to difficulties in readability.
Often there are issues in that you would usually create the initial architecture skeleton first and then develop the modules. There are scripts that can do that for us.
The architecture is still relatively young, and this makes it tricky to get developers who are used to using this architecture.
How do you split the business and representation logic between interactor and presenter?
How can you split third-party SDKs into a Viper paradigm?
Have you own unanswered questions?
Hit me up!