VIPER vs. VIP. Xcode design patterns compared
Learn the pros and cons of VIPER and its new evolution, VIP listed, and choose the proper Xcode design pattern for your iOS application.
Table of Content
What are Xcode design patterns?
If you are one of these people who know the acronym MVC (Massive View Controller), you are surely looking for a replacement.
Ever since SwiftUI appeared, Apple seems to be moving from the proposed MVC model to MVVM. But there are other ways to manage your Xcode project.
One of these ways is Clean Architecture. In today’s post, I’d like to focus on two popular design patterns: VIPER and his younger brother VIP.
Design patterns are a big help for developers. Without them, your code is likely to be messier and contain more bugs. Let alone code duplication, high coupling, or writing standardization.
If you’re not familiar with design patterns or delegation patterns, please read about them first.
What is VIPER?
Let’s start with VIPER.
Its name comes from View - Presenter - Interactor - Router - Entity. VIPER is founded on modules. Each view presented on the device should be a separated module with input and output.
Thanks to this, monitoring and testing a module is much easier than with for example MVC. One of the main features of VIPER is that every module is separated from another. And inside it, all classes have not only different tasks but also steady relations between each other.
For example View (UIViewController) has an input protocol and output protocol. Output is inherited by the Presenter. View gets data from Presenter (via input) and contacts with Presenter via output. It looks like this:
View <- ViewInput <- Presenter
View -> ViewOutput -> Presenter
The same way is at work with Presenter - Interactor relationships, Presenter - Router, and Interactor - Entity. These classes have input protocol with functions to do and implementation of it. The idea is that View can only contact with Presenter (to get data or inform about the current state), while Presenter can only ask Interactor about data. Presenter can also do some minor logic or instruct Router to open other views/modules. The main task of Interactor is to contact with Entity, i.e. with all the business logic used by the app - API, stored data, etc.
If you follow these guidelines, you’ll never have problems with classes doing too much. For example, MVC ViewController usually does the View stuff, business logic stuff, and router stuff. That’s a lot of things to do in one class. Thanks to VIPER you can split tasks between View, Presenter, Interactor, Router, and Entity. And save the hair on your head. ;-)
Another good thing in VIPER is that when it comes to debugging, finding an issue is much easier.
As we said before, classes communicate with each other through protocols. View has an output and input, same as Presenter, Interactor, Router, and Entity. So finding a problem is usually piece of cake, when you know where to search. Let alone that VIPER works like a charm with TDD (Test-driven development).
Of course, VIPER has its limitations and problems but is a much better solution than MVC, and in my opinion, it’s much cleaner than MVVM.
What is VIP?
It’s not only an abbreviation for VIPER. But something wicked this way comes because VIP was made to address some issues of the VIPER architecture.
The main problem that VIP tries to resolve is that in VIPER Presenter can become too big.
As you’ve may have noticed, the VIPER Presenter contacts almost all other classes, i.e. View, Interactor, and Router. In VIP relations between main classes have been changed.
In VIP, View is separated from ViewController and managed by it. So all data displayed on View goes from Presenter through ViewController. Actions are handled by ViewController and delegated to Interactor. It looks like this:
View <- ViewController <- Presenter
View -> ViewController -> Interactor
There are other changes. Router is right now managed by ViewController. So if a user taps the button that leads to another view, ViewController communicates to Router, and Router does all the stuff. In VIPER the way was longer: View -> Presenter -> Router.
Also, Presenter can’t communicate with Interactor. It can only get data from Interactor. So all actions are passed directly from Presenter to Interactor.
Interactor communicates with business logic and sends data to Presenter. All classes are created and linked by Configurator.
As we can see by separating View from ViewController, the last one gets more to do. But it’s not as in MVC or MVVM. ViewController in the VIP design pattern is responsible for handling actions and passing them to specific classes -> Router (opening modules) and Interactor (informing about view state).
VIP addresses problems with too big Presenter while it keeps all advantages of VIPER. I think it’s also better for SwiftUI, thanks to separating UIView from UIViewController. There are still problems with routing, though. SwiftUI has a different approach to navigation (NavigationLink) than UIViewControllers. Navigation is part of View.
VIPER vs. VIP compared. A summary
So what’s better: VIPER or VIP? Well, IMHO it depends on what you want to achieve.
VIP is easier to use, a little bit less structured, and more natural. On the other hand, VIPER will be a good choice if you want to have more structured modules and do important stuff in one place (Presenter).
I think VIP should be treated as an evolution of VIPER. Right now new design patterns try to handle with SwiftUI and I suppose soon we’ll see more tools and patterns similar to VIP.