Table of Contents
The development of the mobile app has changed and evolved a lot in recent years. Thanks to the interest of the developers and the growth of the mobile platforms, every time it is getting more and more common that the development team pays more attention to create reusable components and use best practices in software development like those which already exist in desktop apps, web apps and backend apps. This interest has brought that proliferate, more diverse patterns, able to get a more testable, modularized and reusable code, which caused improvement of the app performance, number of error reduction and quality software development. And this article is about MVP pattern for iOS development.
Here at Apiumhub, we have always focused on creating quality and working software, using in an intensive way the patterns and software development techniques which worked best for each platform, adapting to the clients’ needs.
Let´s focus on explaining the MVP pattern which we have already used on other platforms and that it´s showing that it adapts relatively good to mobile technologies. Just like Android, which has become a “standard by default”.
We will explain to you how we have adapted the MVP pattern to the iOS app development, our proposition and the reasons why we believe that it is a valid alternative to other patterns and how we have plugged our own different development pieces with such iOS pattern.
The MVP pattern was invented in the 90s as a common C++ initiative from Apple, IBM, and HP as an alternative to the MVC pattern. It is an acronym from Model, View, Presenter, which are the vital components of this pattern. There are different implementations of this pattern and some important variances like Supervising Controller or Passive View.
The main difference between the MVP pattern and other UI ones is the full independence between view and model, in other words, the view doesn’t know that a model exists and the other way around.
Pure MVP pattern
Just like in all the definitions of the MVP pattern, in our case, it has 3 separated and clearly differentiated parts but with some peculiarities:
The view is a layout which task is to render the UI and to react to the user events. In the case of iOS, the View will consist of a Protocol that exposes the methods of the user’s events and a ViewController that is responsible for materializing and rendering the UI components and capturing the events that pass to the next component of the pattern, the presenter.
It is responsible for making a connector between the events emitted by the view and connecting them with the model, specifically with the services of the model. Here in Apiumhub, we understand the presenter as a piece of software that connects View with Model, but that lacks logic, the whole state of the data of the view and its behavior is handled in the service and through the presenter, again that returns the transformed data or responds to an event as appropriate. In iOS, usually, the presenter is a class that receives in the init method the view and the service and connects the needed methods. The presenter is normally being used inside an extension class from the main ViewController and it happens when the connection settings are done.
It is the system that contains the logic of the business and it is made up by different software pieces depending on the complexity of the app. In a “Domain oriented” system we will have to structure the layers of the tactic DDD, with some variations coming from the particularity of every front-end app. In the mobile apps, the main parts of the model that we perceive here in Apiumhub are:
1. The services: they are responsible for executing the logic of the business (if there is one) within the domain objects of the App and if it´s necessary to call the repository (o gateway) to have access to the external services or local database. In the iOS case, the service will be made out of a Class and a Protocol. The Class will contain the implementation of the methods exposed by the protocol.
2. The entities: they are the domain objects. They contain logic that reflects the application status. Normally, these objects are kind of DTOs because the logic of the transactions would be in the server, however, there are some exceptions. These objects should never arrive in the view, however, sometimes exceptions can be done when we are talking about simple data transfer objects without logic. Normally, entities are represented as a Class.
3. The repository: They call the external services (APIs or other services) or local databases if the app has them. Just like the services will be made out of a Class and a Protocol.
4. DTO o PresentationModel: These are the objects which are given back from the service and represent the state of a view after the execution or any state change from the app. Usually, they are built from one or more entities. In this case, we will use Structs to carry out the representation of this type of objects, since when representing states of a view, there should be no hierarchy between them.
The main feature of this “Pure” MVP pattern is that the Presenter has no logic and acts like a common plug connector. This allows the presenter to act as an isolated component and it can be re-used again in more than part of the app.
Some of the advantages of the presenter are:
It is a component that expresses directly its intention and responsibility without adding logic that could make us think that does more than one task at the same time.
The presenter centralizes the flow of the events, that helps us to:
- Debug, on the opposite, gets more complicated, especially if you work with binding systems.
- It is easier to trace the origin of the events, the relations between an event and the service responsible for managing it are known at a glance.
- Avoiding “hidden” chain of events because they lack logic and handle the state of the data in the service
- The same component can be reused in different contexts and services.
- You don’t strictly need a test, especially in statically typed environments, because being essentially declarative makes it difficult to introduce errors by logic or change of state of the data
Some of the global features that this pattern brings to the table are:
- The state of the data is always managed from a model level, more specifically in the service layer, when not managed in the server.
- Chain of events is avoided, usually an iteration from a user it´s considered an event
- Since we avoid event chains, the number of calls to the server are minimized, because the logic and the state of the data is solved at the level of service.
- Reduce the coupling and increase the cohesion because each software piece has clear responsibilities and strength to distribute the logic between the model and the View.
- Improves the use of the unit test in order to verify the correct functionality of each software pieces.
To sum up, adapting this MVP pattern in Apiumhub, allowed us to be able to do it extensible to a more variety of platforms, and create a more modulated system with the clear responsibility of the components, which allowed the coverage of the test to be bigger and reusable.
Thanks to all these features, here at Apiumhub, we believe that it adapts and meets our needs, that doesn’t mean that we keep the pattern in continuous evolution and improve it with new features that are introduced in each platform. This allows us to compare this pattern with others that are already being used in the iOS architectures such as Viper, MVVM, Clean Architecture, and more that we will try to evaluate in the next article.
If you are working on a mobile project and you need help with software development, let us know! We would be happy to know more about it!
If you are interested in mobile development, I highly recommend you subscribe to our monthly newsletter by clicking here.