Break the Monolith with (B)Viper Modules

New Features in Realm Obj-C & Swift

We’ve released version 2.7 of Realm Objective‑C and Realm Swift! In this release, we’re introducing improved permission APIs, faster reconnects, password change and applying a few bug fixes to keep your apps running strong.

Introduction (0:00)

It’s becoming a trend that the lifespan of a mobile app be longer, and as such, good architecture is necessary because an app is increasingly diffficult to build.

The motivation for speaking about VIPER is because I believe it’s one of the biggest and most structured architectures out there.

VIPER Architecture Stems From Business Rules (2:21)

Every circle in the architecture diagram represents a different area of the software and its responsibility. The more you move inside the circle, the greater the abstraction becomes. The center has Enterprise Business Rules, which are domain entities of your business. In the airline business, an example would be availabilities.

Defining the Module (7:05)

In the app EasyJet, a user is taken from flight search to the availability screen, then to a summary of the flight they’re trying to book.

It’s important to examine the app with an eye for reusability that’s not too granular, otherwise, the libraries will be too difficult to manage.

Modules should be:

  • Composible - In the case of these screens, they should be components where the sum of them become the modules. The modules can then be built internally, and have their own consistency.

  • Blackboxed - The module should expose a clear API that’s strategical, moreover, it should be completely reusable outside of any predefined architecture.

  • Testable - It should be easy to test.

  • Independent of the user interface and frameworks - this allows for reusability.

  • It must be simple.

We Can Do Better (17:35)

The basic MVVM approach is just user interface and no business logic. The view ideally gets a model, and the view model, renders it, but we are left with the view model itself having to convert data from entities to the view model itself, and this is bad.

Routing

This is related to the routing/navigation. The view model is going to tell the router to go to another module.

Take for example in the Apple weather app, where there are a list of cities, and their weather. There will be a router contract/protocol WeatherListRouter that allows the user to navigate to a detail screen.

You can also navigate to add a weather location.

protocol WeatherListRouter {
	func navigateToDetail(location: Location)
	func navigateToAddWeatherLocation()
}

In this instance, the view model is now actually a presenter that sits in the middle, and it’s the model of the view.

WeatherListView

protocol WeatherListView {
	func displayLocationList(vm: LocationListVM)
	func displayError(errorMessage: String)
}

This tells the presenter to load the content. The view then responds to the presenter to display the weather detail.

Who’s talking to the view?

The presenter interfaces with the view.

struct LocationListViewModel {
	let locations: [LocationViewModel]
}

struct LocationViewModel {
	let locationId: String
	let name: String
	let detail: String
}

It tells the view to display the location list.

This next component is very important and is the interactor. If you watch the Uncle Bob video on clean architecture it actually goes exactly the opposite way around. It starts from the interactor because it is so important.

Interactor

public protocol WeatherListInteractor {
	func locations() -> [Location]
}

The interactor knows nothing about presentation logic. It only knows about services and entities, and applies all the application business rules to the specific module being built.

Finishing Touches? (30:29)

The Builder

Because I don’t want to give a component a responsibility it doesn’t deserve, I want a builder that is strictly for building. This deserves to be separated because it’s the key for usability. All of those components are defined by protocols.

public protocol WeatherListBuilder {
    func buildModule() -> UIViewController?
}

The builder is in charge of creating other elements and linking them together.

Resources

(B)Viper Example Repo


Nicola Zaghini

Nicola Zaghini

Nicola Zaghini is a software architect at Mobile Travel Technologies. He has been developing mobile apps since the first iOS SDK was released, from indie game development to major airlines and travel companies. Prior to that, he enjoyed Java development as professional and researcher in academia. He is currently in charge of mobile architecture in MTT and helps teams deliver amazing apps.