Scalable iOS Architecture Using MVVM
In this article we shall examine Scalable iOS Architecture Using MVVM. MVC vs MVVM topics can be seen quite often on developer forums. Indeed, while to some this topic is new, it has already made some people sick of it. But which one is better after all?
In this article, we will finally try to get to the bottom of this question. Here we look at the key aspects of creating a mobile application architecture and examine which pattern is better in the context of developing a scalable iOS application.
Factors that may influence your choice
Stakeholders not only want the system to provide the necessary functionality, but also a host of other non-functional requirements. In addition, some of the requirements are contradictory.
When selecting an architecture, the main factors to consider are:
- Development effort e.g. scope; complexity (technical and logical); clarity of goals;
- The main development goals (product goals), resulting from the system requirements: efficiency, extensibility (scalability, ease of adding new features), etc.
- project goals such as maintainability; cost; implementation time, etc.
- Logical reasoning. It is important to ensure that the decisions that led to the creation of that architecture are documented and that the rationale for those decisions is justified.
- Architectural style. Architectural style defines the nomenclature of components and types of connecting links, as well as a set of conditions under which they can connect.
Features of a good app architecture
The main criteria for good architecture are the ability to make the development and post-release maintenance process easier and more efficient. Well-designed software will be much easier to extend and change as well as to test and debug. Thus, we can formulate a list of quite reasonable and universal criteria:
- System efficiency. First of all, the program should solve the tasks and perform its functions well, and in different conditions.
- System flexibility. The faster and easier it is to make changes to the existing functionality, the fewer problems and errors it causes.
- Expandability of the system. The ability to add new entities and functions to the system without breaking its basic structure. And it should be done in such a way that the introduction of the most probable changes requires the least effort.
- Scalability of the development process. The architecture must allow you to parallelize the development process so that a lot of people can work on the program simultaneously.
- Testability. Code that is easier to test will have fewer bugs and work more reliably.
- The possibility of reuse. You’d prefer to design a system in such a way that its fragments can be reused in other systems.
- Maintainability. As a rule, many people work on a program. Good architecture should allow new people to understand the system quickly and easily.
What are the architecture design patterns?
Building an architecture requires off-the-shelf unified solutions. These are the ones that can significantly reduce development costs. Templates greatly simplify the whole process, because it becomes easier for developers to communicate using the same constructs. In addition, it significantly reduces the number of errors.
And that is why there is a concept of design pattern in development for iOS. In fact, it is a solution to a recurring problem. Let’s take a look at the most popular ones.
MVC
MVC is the most basic pattern offered by Apple back in the day. It consists of three parts Model, View, and Controller. The vast majority of developers use it. However, it is not always the best solution.
Multiple Views can be attached to a single Model so that you don’t have to change the Model code. For example, you want to show tabular data as a table, a histogram, or a pay-chart. The development of business logic does not depend on view development and vice versa. This means that it’s possible to have several people at the same time chisel the code for one feature.
MVVM
MVVM architecture (Model-View-ViewModel) was created at Microsoft to work with WPF and Silverlight, but has gained popularity far beyond WPF applications due to its elegant modularization.
The ViewModel is a handy mediator, detached from the world of UI and Data Access, which means it is easy to test and re-use on other platforms, if you suddenly need to make an application for tvOS, for example
The main difference between MVC and MVVM is that the latter is well-suited for experienced mid-sized teams working on a project with a large number of views. MVVM is especially good for projects which require a strong separation of business logic from view rendering logic. It is common in cross-platform applications or apps which may need a satellite client for another platform (tvOS, watchOS).
Because of the strong separation, MVVM allows multiple developers to work on a single feature simultaneously with little overlap in the code. It is the easiest way to understand and implement an architecture.
MVP
Unlike MVC, in MVP (Model-View-Presenter) the presenter contains all of the UI logic and is responsible for synchronizing the model and view. When the view notifies the presenter that the user has done something (e.g., pressed a button), the presenter decides to update the model and synchronizes all changes between the model and the view.
MVP turns out to be a good alternative to MVC if chosen consciously to solve a particular problem. Otherwise, it feels like “too much extra code”. MVP works well for small teams, but in a large project with many developers, it leads to a lot of merge conflicts that no one likes to clean up.
VIPER
This architectural pattern appeared relatively recently and is a logical continuation of the MV-X family. This pattern is intended to increase the level of abstraction, reduce code relatedness, and solve routing problems in the application. The application in the VIPER approach is broken down into modules (rather than screens) and external dependencies.
The benefits include increased testability of the Presentation layer of the application. However, there is also a sharp increase in the number of classes in the project, the complexity of creating a new module. Some of the principles are not directly related to UIKit and Apple’s approaches.
Of all the patterns listed, we are most interested in MVC and MVVM as the most popular. Now that you have an idea of the basic types, let’s figure out what’s best for developing a scalable iOS application.
Scalable iOS Architecture – Which one is the best for scalable iOS architecture?
In MVVM Controller user events come to us, like in apple MVC, from View, and through “binder” are processed by ViewModel. ViewModel sends messages to Model and when a model changes, ViewModel will notify View with observable properties. The main difference here is that the ViewModel does not contain a direct reference to View, while in MVC, the Controller itself contained a reference to View.
Usually, View also does not contain a reference to ViewModel. Instead, there is a so-called binder. When Microsoft created the MVVM pattern, they tried to solve the problem of boilerplate code to connect the presented data to the View. The XAML-based framework helped in this, keeping the View up-to-date through the logic of the ViewModel, without requiring a single line of code from the developer.
MVVM solves exactly the same problem as MVC, but with less boilerplate code at the expense of the framework. Just a cleaner and more automated approach.
MVVM has a number of key advantages over MVC when it comes to the scalability of iOS applications.
- Repairability. Making changes in this pattern is greatly facilitated by the separation between code types.
- Testability. The granularity of the code makes it easier to test the product.
- Extensibility. This pattern allows you to replace or add new features more easily due to the specifics of the architecture.
The features in this pattern make it easy to make changes to the user interface and model. This makes it much easier to refine the application after its release.
MVVM in SWIFT
It’s worth noting the peculiarity of data bindings in MVVM. In MVVM, you need a way to map view model outputs to views. Great help here is a utility that provides a simple mechanism for binding views to the output values of the view model. There are several ways to do this binding:
- Key-Value Observing or KVO: a mechanism for using key paths to observe a property and be notified when that property changes.
- Functional Reactive Programming or FRP: a paradigm for handling events and data as threads. Apple’s new Combine framework is its approach to FRP. RxSwift and ReactiveSwift are two popular frameworks for FRP.
- Delegating: Utilizing delegate methods to pass notifications when values change.
- Boxing: Utilizing property observers to notify observers of a value change.
Here’s what the code above does:
- Each Box can have a Listener that Box notifies when the value changes.
- Box has a generic type value. The didSet property observer detects any changes and notifies Listener of any value update.
- The initializer sets Box‘s initial value.
- When a Listener calls bind(listener:) on Box, it becomes Listener and immediately gets notified of the Box‘s current value.
***
Ref Scalable iOS Architecture, It’s time to answer the question of who wins the MVC vs MVVM battle? We think that compared to MVC, MVVM is the clear winner.
The main advantage of MVVM is that the code is much clearer because the UI is strictly separated from the business logic. Although an inexperienced programmer might find it difficult to deal with data binding in this pattern, a seasoned professional is more likely to use it to develop a scalable UI application.