Clean-MVP with Swift

We all know and heard about architecture patterns used in Software Engineering and the Swift community specifically, starting from our old good friend MVC and to the most recent VIPER, Elm, and TCA (The Composable Architecture). We also heard about Clean Architecture, the architecture created by Uncle Bob. But have you heard about Clean MVP? It applies the concepts and principles of Clean Architecture to the known MVP UI design architecture, it's not only applied to MVP though, it can be extended to other architectural patterns that we know, like MVVM, it becomes Clean-MVVM! But what are they? And why do we need it?

But first, let's talk about the family of MV* architectures...

UI Design Patterns

I love to call MVC, MVP, MVVM, and all other patterns in this category as: "UI Design Patterns" or "UI Architectural Patterns", these patterns solve the communication issues that happen between 2 major components: the Model and the View. Then, the Controller component was introduced to the View and the Model components to define the data binding technique between them. Giving the Controller a different name (for example, Presenter) doesn't change the fact that it was introduced for that reason, the Controller links the View and the Model with one of the communication patterns. That's because they don't care about other important components and layers in our apps like the "Database" layer or the "Networking" layer, the View is concerned with the presentation layer of the app and the Model is concerned with the Entity layer of the app.

Every app uses one of the UI Design Patterns, but the issue with achieving scalability to the apps isn't related to your choice of UI Design Pattern, scalability is a factor of the whole app, which means it includes more layers other than the ones contained in the UI Design Pattern.

On the other side, Clean Architecture helps us to see a bigger picture of the other layers when creating our apps, it shows how they communicate with each other and how they connect to our UI Design Pattern of the app. The concepts of Clean Architecture are clear and they can be applied to the UI Design Pattern used in your app but with different levels of refactoring, and the adoption of Clean Architecture principles is also confined with your app's logic and requirements. In this article, we will talk about how to apply Clean Architecture principles to MVP UI design pattern, here is when the Clean-MVP comes.

Clean Architecture Principles

Clean Architecture is developed, as said by Uncle Bob, to combine other different architectures into one idea. In Swift, we have multiple applications for Clean Architecture, like VIPER and VIP architectures, they are applications on how to adopt Clean Architecture principles in iOS apps.

The following diagram shows the general idea of applying Clean Architecture components:

The following diagram shows what we will be doing to introduce the Clean-MVP:

From the diagram, we can identify the main components, and they are:

1- View: This is the "V" in the MVP architecture and it represents the ViewController, it handles everything related to the views being presented and passes user interactions with the UI to the presenter to handle it.

2- Presenter: This is the "P' in the MVP architecture, the presenter handles the passed user interactions from the view and it updates the view based on the Business Model in our app. The presenter doesn't handle logic, it only holds the models in it.

3- Interactor: This is our gateway for services in the app, such as database and networking, it's our communication channel with those services, the presenter holds a reference to the interactor and asks it to handle the Business Logic in the app.

4- Navigation: This is the component that handles navigation through the app. This can be implemented using the Coordinator pattern or any simple navigation logic will do the work, the main idea is to separate the navigation logic from the View layer (away from the ViewController).

After laying out our base and our components, we can talk about achieving scalability for this architecture, in our case, we will be talking about feature scalability. Assume that we have multiple networking services for our project, for example, building a news app, you can have multiple network services where each one is responsible for fetching a specific type of news. The Interactor component will be responsible for handling this part, where it contains everything it will need to interact with the server and fetch the needed data.
Also, the Database can be handled with lots of queries, a manager for our database can be created and also can be easily managed by our Interactor component.

What about navigating from one view to another? No problems at all, the Navigation component defines a contract for all views so that each view doesn't know anything about the presentation style or how another view will be presented. The Navigation component is used to define the routes in the app and it doesn't require that each view knows about other views. This helps in maintaining a clear app flow in our project.

Benefits of Clean-MVP Architecture

As we talked at the beginning of this article, Clean-MVP architecture is a try to apply the principles of Clean Architecture to the MVP UI design pattern, simply because it puts scalability in mind and that's something we all do with our apps, by applying those principles, it gets the benefits of applying Clean Architecture to your codebase. In my humble opinion, Clean-MVP has the following benefits:

  • Testability. Testing is considered an easy task in Clean-MVP since it follows the Single Responsibility Principle, each component is defined and maintained on its own, not just that, the way they are maintained makes it easy to mock them, allowing us to use Dependency Injection for them.

  • Easy to extend. It's easy to extend the functionality of the components in Clean-MVP since it promotes the Open-Closed Principle, which is a principle that can be easily followed in Swift using Generics and Protocols.

  • Maintain a strong "Screaming Architecture". Screaming Architecture, as defined by Uncle Bob, is a term used when we can, just by looking at a new project at a glance, get the core idea of what the project does and what it is about. It might be something minor for some people, but being able to tell what something is doing just by quickly looking at it is something that cannot be overlooked. Clean-MVP makes it easy to predict and to know what each component does, the components are considered self-documented, so it's also self-described.

  • Easy to debug. Again, because the Clean-MVP components are well-written and each component defines its requirements and behaviour clearly, it makes debugging becomes an easier task because as a developer, you can easily predict the way the flow of the app will go and it's easy to trace the calling stack in your debugging session.

  • Suitable for both small and big teams. One of the very important benefits in my opinion, Clean-MVP can be applied for both large projects with a big number of developers in a team (Or even maybe multiple teams), or smaller projects where a small number of developers are working on that project.

  • And more...

Of course nothing is a bullet-proof solution, the needs and requirements of your project defines the way your app flows are defined, this doesn't mean that you can't adopt Clean Architecture in some cases, it's just different for each case that you have.

There will be another article where we will take Clean-MVP into action create its components, showing how easy it can be created and maintained, see you soon!