iOS Architecture — The VaMPiRe: Part 1

How my favourite iOS architecture for medium/large projects works. A new approach, similar to the Viper one.

Marco Guerrieri
Kin + Carta Created
4 min readJun 23, 2022

--

During my career as an iOS developer I have worked and tried different architectures in the app development. Like any beginner I started with the classic MVC pattern, and then moved on to the various MVPs, MVVMs, VIPER etc, trying also functional and non-functional programming patterns.

After all my experiences, I have come to find what suits best for me in various situations and this is what I want to talk you about. But first, lets make some necessary premises:

  • There is no flawless architecture because it all depends on requirements, team preferences and type of project
  • I have always preferred write verbose but more intuitive codebases to help the team in reviewing code and also to help whoever take over the development of the project
  • The components name in this architecture can be counter intuitive for someone because they are used differently in other architectures, obviously can be changed as you like
  • I am not a lover of third-party libraries to simplify things, for example I prefer to personally build the Mocks used in the Tests, this to avoid heavy dependency on external code. This doesn’t mean I completely gave up third-party libraries, but I evaluate every time if I can develop something or if it would be really beneficial to use a third party library

INTRODUCTION

This new architecture approach take takes inspiration mostly from the VIPER architecture, but with some differences that makes it, in my personal opinion, more readable and intuitive.
The different layers of the app are separated in a pretty clear way and using the single responsibility principle (without being too restrictive) where each component is a layer dedicated to a particular task, for example handle the user interface, the business logic, the routing, the network data fetch etc.
Each component is connected to one or more of the others, and all of those collaborates to build the entire app flow, and everything is extendable and maintainable.

This post came also with a small sample project, its very simplistic and with stub/fake functions in it, but I think its good enough to have a clear view of how the various parts of the app interacts. You can find it here:

GOALS

The introduction is quite explanatory, but to make sure we are clear about the objectives of this architecture, let’s make them more explicit with this small list:

  • Decoupling UI/UX, business logic, navigation, network layer and models
  • Have all the components easily testable
  • Make the codebase friendly and easy to explain to new starters
  • Provide easy ways to modularise the codebase if needed

SECTIONS & SCENES

To have a clear understanding lets start with the concept of Scene and Section.

A Scene is considered the set of files that are used to create and manage the state and the interactions of a screen presented to the user. Basically a ViewController and all the associated files.
An app can be then seen as a set of scenes shown to the user, each scene has its layout, its functionalities and its connection to other scenes.

A Section is considered an entire part of the app that contains one or more scene. But how do we define what is part of a section or another?
Basically a Section is made by the scenes that are involved in a particular flow dedicated to a specific functionality, this means that it’s up to you to define what scenes go in a section and whether to split it in different sections.
Usually I tend to put together in one section all the scenes that are part of a unique navigation flow and treat them the same.

For instance: if you have a scene that can be reached from different parts of the app (e.g. settings), it will end up with its own section. Whereas a scene that can only be accessed from a single entry point (e.g. registration, login, etc.) can easily be accommodated in the same section.

Lets see now a sample flow with various sections and their scenes:

In this example we can find:

  • Home Section with Home scene
  • Events Section with EventsList, EventDetails and BookEvent scenes
  • Settings Section with Setting scene

Now that it’s clear the difference between a Section and a Scene, lets have a quick look to the main components that are used in this type of architecture, alongside with any helper/factory/cache you need:

  • Routers: navigate the app and instantiate the scenes
  • Contracts: declare the protocols used in a Scene and the structure of the data exchange between the various parts
  • Presenters: contains the business logic of a scene
  • ViewModels: container of the state/data/content used to configure the UI of a scene
  • ViewControllers: the UI and the listener of any interaction made on it
  • UseCases: retrieve data via Network API calls

And now I can also explain finally why I chose the VaMPiRe name:
View viewModel Presenter Router

What’s Next

In Part 2 we will see in detail these components, how they work and how they interact with each other

--

--