In this article, we are going to discuss how to get started with VIP Architecture in iOS. We shall begin by looking at certain theoretical backgrounds to understand the basic working and data-flow in VIP. Following which we will dive into some real code.
Topics that shall be covered are —
- Why VIP?
- VIP: View Controller, Interactor, Presenter
- VIP Cycle and Data flow
- Implementing VIP in iOS
To begin with, you may have worked with various system architectures such as MVC, MVVM, ReactiveCocoa, or VIPER which have been “good” and did a great job until recently. These architectures have been helpful in building and publishing various apps. However, they have not been “good” in efficiently managing the problems of scalability and maintenance.
This is due to the underlying issues in the design and data flow patterns of these architectures that make them challenging and nonreliable often leading to Massive View Controller. Further, there may be bugs and difficulties in adding new features which makes the use of these architectures more cumbersome.
Clean VIP Architecture is what offers a solution to the above-mentioned problems.
VIP: View Controller, Interactor, Presenter
VIP is Uncle Bob’s Clean Architecture. It is one of those system architectures that follow clean architecture guidelines about system design, component design, data flow between different system layers, and others. It consists of three core components:
- ViewController: It is a UIViewController that we encounter frequently with the mere difference that in VIP it has only two responsibilities, namely, getting user inputs and rendering UI. In addition, it also holds a
strongreference to Interactor.
- Interactor: In VIP, Interactor is a
concrete classwith the functions of making various API calls and maintaining data and business logic. It holds a
strongreference to the Presenter.
- Presenter: The presenter is also a
concrete classthat holds a
weakreference to Controller. It performs the functions of creating and passing data to ViewController via ViewModels and validating data and actions for ViewController.
Hence, the responsibilities in VIP are nicely divided into various classes leading to a clear separation of UI and business logic, unlike other architectures.
Note that a few other entities like — Models and Routers that facilitate navigations and data maintenance have not been broadly discussed here.
VIP Cycle and Data flow
The VIP cycle and data flow is as follows—
ViewController → Interactor → Presenter → ViewController
ViewControllertakes user inputs and passes them to
Interactorin form of requests.
Interactorprocesses these requests (validates and executes them) and passes the response to the
Presenterprocesses these responses (validates and creates ViewModels) and passes them to
ViewControllerto update/render UI.
From above, it is clear that the data flow in VIP is uni-directional, from View -> Interactor -> Presenter -> View. This way VIP tackles certain problems that arise in bi-directional data flow architectures like MVC, MVVM, and others.
VIP in iOS: Implementation
Now comes the final step of implementing VIP in an iOS Project.
For simplicity, the example is restricted to only one view, which displays a list of Movies that have an
imdbRating > 8.0 . This is achieved via a UITableView and a set of prefetched movie data stored in a JSON file in the App bundle.
Models — Movie.swift
In order to display the above data, we will create
Movie , a model that will map data for each movie.
Worker — FileReader.swift
This is a Worker class that reads data from the static JSON file saved in the App bundle.
FileReader is a Worker that has a static method
getMovies(:)to read data from JSON files and send
Result in a
ViewController — MoviesListController.swift
This is a
UIViewController class that controls the UI of the App.
Notice that the controller in the above code holds an
optional reference of the
interactor , which is used to pass user and data requests from the controller to interactor as is evident from the usage of the method
MoviesListController also has a
render(props:) which is the only method responsible for updating the view as is suggested by the theory. This helps in debugging and maintaining update logics for the view.
The following snippet shows the
interactor performing its core responsibilities —
getMovies(:) to get data and
processMovies(:) to implement business logic.
interactor fetches data for
movies , processes it and then triggers an update in the
presenter . Hence, passing response from
interactor -> presenter
Presenter — MoviesListPresenter.swift
This section shows the
presenter , performing its core responsibility— updating
controller with the new data passed to it.
It is worth noting how in the method
presenter reads the current state of controllers
viewProps and updates only the required data and then triggers the
render(:) method that would start the view update. So, passing data from
presenter -> view . With this, the VIP cycle which is a
uni-directional data flow is completed.
Router — Router.swift
In VIP, Router is a class facilitating navigation from one view to another. Generally, each view has its own
Router but, it is not always necessary as there can be a
global Router class that may be divided into various sub-routers whilst maintaining the navigation stack. In the example below, a global
Router is created that has its own
Observe how the method
showMoviesListView() is used to show the Movies list view. This method instantiates the controller, presenter, interactor and passes the reference of one entity to another. This is a very apt representation of the VIP cycle.
Once all the relations are established, the view is pushed onto the navigation stack which brings us to the end of VIP implementation.
The only thing left now is to call the
startNavigation() to start navigating and presenting views. This can be done either in
SceneDelegate classes. Based on my
deploymentTarget i.e. iOS 14.2, I have done that in
This brings us to the end of the article. All that is left now is to run the App.
Hope that now you can try and create your own iOS Apps that follow the Clean VIP Architecture and play around with your code in this amazing way whilst noticing the immense scope of VIP.
If you want the complete source code of the above example, visit the Github repository given below—
Permalink Failed to load the latest commit information. Start learning and implement VIP architecture in iOS 14. Create a…
See you soon! Until then,