About a year ago I met such a wonderful pattern as the
Viper . And now I want to talk about my problems, as well as about their solution.
Introduction
Having read tutorios about Viper, I started trying to create a new project on it. As a result, my Viper looked like this:
A base class is signed next to each block. Arrows indicate links between objects (weak dotted line).')
This scheme does not solve an extremely important problem. How to locate modules in UINavigationController? Due to the fact that the navigation stack needs to add heirs to the UIViewController class.
- in the router you will have to pull the view through the presenter and explicitly indicate that this is a UIViewController
- after adding a view to the UINavagationController, the view of the strong link counter will increase to 2. In the future, you will have to manually remove the viper module from memory.
In this approach, some incompatibility of Viper and UIKit is evident.
How to make friends Viper and UIKit
First of all, you need to understand how to move from Apple MVC to Viper. MVC quite easily decomposed into view, presenter and interactor. But viper has an additional layer - the router. And at this point, I propose an alternative point of view (at least on the Internet, I have not seen anything like this).
It became noticeably more UI components. Now let's see why everything is so, well, or almost. As a basis for my reasoning, I will use this
article .
It says:
Presenter / Presenter
Presenter is PONSO, which basically consists of logic to control the UI. It collects input from user interaction, so it can send requests to Interactor. Presenter also gets the results of Interactor and converts the results to the state that is most effective for display on the View.
Entities are never transferred from Interactor to Presenter. Instead, simple data structures that have no behavior are transferred from Interactor to Presenter. This prevents any real work in Presenter. Presenter can only prepare data for display on the View.
If, in the capacity of a presenter, to take not a PONSO, but a UIViewController, what will change? Yes, the presenter will be responsible for displaying the module, but only under the hood of the UIKit. All methods of the life cycle can be regarded on the same principle as the events from the view buttons. That is, the view tells the presenter that the viewdidload has happened and something can be done about it. All rendering logic remained on view.
Now let's take a look at the router (in the article it’s shown as wireframe. I usually divide it into router and moduleManager)
Wireframe / Frame
Routing handles navigation from one screen to another, as defined in the wireframes created by the interaction designer. The wireframe object is responsible for routing. The wireframe object owns UIWindow, UINavigationController, etc. objects. He is responsible for creating the Interactor, Presenter and View / ViewController and for setting the ViewController. Since Presenter contains logic to respond to user input, Presenter knows when to go to another screen. Wireframe knows how to do it. So Presenter is a Wireframa user.
There is a question. Why router can not be UINavigationController? Why do we still need a bicycle when UIKit has its own routers - these are UINavigationController and sympathizers. In such classes, the basic logic has already been laid.
What does this approach solve?
- less code, everything is done for us
- clear code for someone unfamiliar with Viper
- UIKit is now responsible for working with memory; you don’t have to destroy modules by hand
- simple integration with third-party libraries that accept UIViewController at the entrance
As an example, I created a small demo
project . I hope for an objective discussion.