How to fit VIPER into your app

Rasmus Styrk
3 min readDec 18, 2019

Many VIPER guides focuses only on VIPER and not how it fits in with the rest of your application. If you want to get our view on a good overall architecture for your app and use VIPER, then this is an article for you. VIPER can be switched out with any other architecture if you want.

A practical example and explanation on how to setup viper together with the rest of your application.

Consider the following diagram

Here we are integrating VIPER into other modules like AppCoordinator, Data Repositories and a Session Manager. We found that this is a good layout for many applications and i will try to explain how we did it.

Each VIPER module is made up like this

How we implemented VIPER

But this article is not directly about VIPER. If you want a more in depth explanation of VIPER, then i recommend reading Implementing VIPER Architecture Pattern for iOS.

Let’s discuss the objects and their responsibility in our architecture

Components [folder]

A collection of reusable components, like buttons, views etc. Components is something the user can see.

Helpers [folder]

A collection of reusable helpers, like dateformatters etc. Helpers is something that computes stuff.

AppDelegate

Handles starting the application and booting the AppCoordinator together with SessionManager and DataRepository. Forwards lifecycle messages to the AppCoordinator.

SessionManager

Manages the user session — is the user logged in or not and also takes care of the login/logout process.

DataRepository

All communication back and forth between the app and the backend and handles stuff like caching for offline use.

AppCoordinator

Coordinates the main lifecycle events of the app — takes decisions on starting up, delegating messages and switches the main app flows depending on login status.

A typical app have 3 overall “areas” (or states) where the user can be and therefore it’s a good place to have the coordinator to coordinate this depending on user state.

  • Splash on load
  • Login flow when user is logged out
  • Normal App flow when user logged in
How AppCoordinator manages state and flow

Below you can see how we initialize and starts the coordinator.

AppDelegate.swift

You need to initialize a DataRepository and a SessionManager and pass them to the AppCoordinator. We like to avoid singleton classes and therefore we need to inject the dependencies that are required for the coordinator and modules to run.

The code for the app coordinator looks like this

AppCoordinator.swift

Now the app will switch out the active VIPER module based on user state. The coordinator could also take care of delivering messages to the right modules or queue them until the user is logged in or telling the data repository to save its state when user exits the app.

Just to give an example of how the actual VIPER module is started you can check out the following Router for the LoginSelectionModule. (Where you choose how to login or if you want to sign up).

LoginSelectionRouter.swift

That’s about it and how we integrate VIPER into our iOS apps. Feel free to comment if you have any thoughts.

--

--

Rasmus Styrk

I work as a software developer with years of experience within the field of web, apps and server architecture.