0% found this document useful (0 votes)
16 views17 pages

iOS Architecture Patterns M

Uploaded by

champsdload
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
16 views17 pages

iOS Architecture Patterns M

Uploaded by

champsdload
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 17

A class should have one reason, and one reason only, to change.

That is, a class should only have one responsibility.

Open–Closed Principle (OCP)

We must be able to extend a class without changing its behavior. This is achieved by abstraction.

Liskov Substitution Principle (LSP)

In a program, any class should be able to be replaced by one of its subclasses without affecting its operation.

Interface Segregation Principle (ISP)

It is better to have different interfaces (protocols) that are specific to each client than to have a general interface.
Also, a client would not have to implement methods that it does not use.

Dependency Inversion Principle (DIP)

High-level classes should not depend on low-level classes. Both should depend on abstractions. Abstractions
should not depend on details. The details should depend on the abstractions. What is sought is to reduce depen-
dencies between modules and thus achieve less coupling between classes.

How to Choose the Right Architectural Pattern

We have just seen the advantages that our applications have a good architecture offers us. But how do we choose
the right architecture pattern for our project?

In the first place, we have to know some information about our project and the technology that we are going to use
since we have seen that some architecture patterns are better adapted to some projects and other patterns to oth-
ers.

Therefore, we must take into account, for example:

• The type of project


• The technologies used to develop it
• Support infrastructure (servers, clouds, databases…)
• User interface (usability, content, navigation…)
• Budget and development time
• Future scalability and the addition of new functionalities

If we take into account everything seen so far, the choice of a good architecture pattern (along with the use of
design patterns and SOLID principles) will allow us to have the following:

• A scalable application: A good architecture pattern should allow us to add new features and even change
some of the technologies used, without having to modify the entire application.
• Separation of interests: Each component should be independent of the code point of view. That is, to func-
tion correctly, a component should only be aware of those around it and nothing else. This will allow us, for ex-
ample, to reuse these components or simply change them for others.
• A code easy to maintain: Well-written, structured code without repetition makes it easier to understand, re-
view, or modify. Also, any new developer joining the project will require less time to get hold of.
• A testable code: The previous points result in the fact that it is easier to test a code if the functionalities are
correctly separated than if they are not.
• A solid, stable, reliable, and durable code over time.

Most Used Architecture Patterns

From a generic point of view of software development, there are numerous architecture patterns, but we will focus
From a generic point of view of software development, there are numerous architecture patterns, but we will focus
on the most used for the development of iOS applications:

• Model–View–Controller (MVC)
• Model–View–Presenter (MVP)
• Model–View–ViewModel (MVVM)
• View–Interactor–Presenter–Entity–Router (VIPER)
• View–Interactor–Presenter (VIP)

We will start with the best-known model and the one that every developer usually starts working with, the MVC.
From here we will work on models that derive from it, such as the MVP and the MVVM, to end up with much more
elaborate models of higher complexity, such as the VIPER and the VIP.

After these architectural patterns, we will see, in a more summarized way, some more patterns, perhaps not so
used or known, but that can give us a better perspective of how to structure an application. Examples of these
types of patterns are RIBs (developed by Uber) and Redux (based on an initial idea of Facebook for a one-way archi-
tecture).

In Search of a “Clean Architecture”

The “Clean Architecture” concept was introduced by Robert C. Martin in 2012,2 and it is not an architecture, but a
series of rules that, together with the SOLID principles, will allow us to develop software with responsibilities sepa-
rate, robust, easy to understand, and testable.

Clean Architecture Layers

According to this philosophy, for an architecture to be considered “clean” it must have at least the following three
layers: Domain Layer, Presentation Layer, and Data Layer (Figure 1-2).
Figure 1-2 Scheme of the layer structure in Clean Architecture. Dependency rule arrows show how the outermost layers depend on the innermost ones and not the

other way around

Domain Layer

It is the core of this architecture and contains the application logic and business logic. In this layer we find the Use
Cases or Interactors, the Entities, and the Interfaces of the Repositories:

• Use Cases or interactors: They are in charge of defining and implementing the business logic. They control the
flow of information to and from the Entities. They can work with one or more entities and access their methods.
• Entities: These are simple objects (which can be simple data structures or can also contain methods) that con-
tain the business rules.
• Repository interfaces: They contain the definition of the methods that will be implemented in the Repositories.
Repositories are responsible for obtaining and passing data from databases, servers, etc.

This layer has no external dependencies, so it is easily testable (Use Cases) and can be reused in other projects.

Presentation Layer

This layer contains all those elements that show information to the user or that receive their interaction.

The Presentation layer also includes those components, such as ViewModels or Presenters, that help prepare the
data to be displayed on the screen.

The ViewModels or Presenters are also in charge of executing the Use Cases. The Presentation Layer only depends
on the Domain Layer.

Data Layer

It contains the implementation classes of the Repositories and the data sources such as databases, user prefer-
ences, or access to servers. In the same way as the Presentation Layer, the Data Layer only depends on the Domain
Layer.

The Dependency Rule

For this type of architecture to work correctly, we must apply the so-called Dependency Rule. According to this
rule, the inner layers must not know the outer layers (i.e., no variable, method, etc., of an outer layer is mentioned
in a more inner layer).

Advantages of Applying a Clean Architecture

The application of a Clean Architecture in our projects will give us a series of advantages (some of which we have
already seen in the introduction to Software Architecture):

• Testable: The fact that the business logic is isolated in its layer, and that it does not depend on the rest of the
layers, makes it easily testable.

In addition, this same separation by layers allows them to be tested separately and more easily locate any
possible error.

• Independent of frameworks: The code must be independent of specific libraries.


In other words, we can change one library for another without the need for major changes in the code and
without the internal layers stopping working because of it. This is achieved by preventing our code from having
direct dependencies on these libraries.

• Independent of the user interface: The user interface is the outermost layer and only displays the data sup-
plied by the presenter.

Therefore, we must be able to modify it without affecting the most internal part, the business logic. In other
words, the user interface must adapt to changes in business logic and not the other way around.

• Independent of data sources: In a similar way to what was explained for the independence of the user inter-
face, we must be able to change the data sources (local, external databases…) without affecting the business
logic, since it is these sources that fit the business logic.
• Independent of external elements: The business logic must be independent of everything that surrounds it,
which must allow us to change any part of the rest of the system without affecting it.

MyToDos: A Simple App to Test Architectures

To work with the different architectures that we have mentioned before (MVC, MVP, MVVM, VIPER, and VIP), we
are going to create a simple task management application, which is, usually, one of the first applications that a de-
veloper usually does.

App Screens

Our MyToDos app will allow us to work the navigation between different screens (create lists, create tasks…); use a
database to save, update, or delete tasks; and, finally, manage user interactions on the different screens.

Launch Screen

It is the screen that appears when loading the application (Figure 1-3).
Figure 1-3 Launch screen

Home Screen

This screen shows the lists we have created. If we haven’t created any list, an “Empty State” will appear to tell us to
create our first list.

For each created list, we will be able to see the icon that we have associated with the list, the title of the list,
and the number of tasks that compose it (Figure 1-4).
Figure 1-4 Empty state on Home screen

The user can interact on this screen at three points:

• Using the Add List button, which will allow us to create a new list
• Selecting one of the lists to access its content (Figure 1-5)
• Deleting lists by a swipe gesture on the list (Figure 1-6)

Figure 1-5 Access tasks list on select cell


Figure 1-6 Delete list on swipe cell

Add List Screen

This screen is navigated through the Add List button on the Home screen. Here, the user has to indicate the title
that will be given to the list and select an icon from those that are shown (Figure 1-7).
Figure 1-7 Add List screen

When you select the Add List button, the entered information is saved in the database (Core Data) and you return to
Home.

If the user wants to return to Home without creating any list, they simply have to select the button with the return
arrow located at the top left of the screen.

Tasks List Screen

This screen is navigated by selecting one of the lists that appear in the Home. If we do not have any task created,
an “Empty State” will appear indicating how to create a task (Figure 1-8).
Figure 1-8 Tasks List empty state

The user can interact on this screen at three points:

• Using the Add Task button, which will allow us to create a new task (Figure 1-9).
Figure 1-9 Tasks List screen with an added task

• Selecting the circle to the right of each task will allow us to mark it as done (Figure 1-10).
• Deleting tasks using a swipe gesture in the list (Figure 1-11).

Figure 1-10 Task checked as done


Figure 1-11 Delete task

Any modification on this screen (change the status of a task or delete it) is automatically saved in the database.

If the user wants to return to Home without creating any task, they simply have to select the button with the return
arrow located at the top left of the screen.

Add Task Screen

This screen is navigated through the Add Task button on the Tasks List screen and is displayed as a modal. Here, the
user has to indicate the title that will be given to the task and select an icon from those that are displayed.

When you select the Add Task button, the entered information is saved in the database (Core Data) and you are re-
turned to the Tasks List screen.

If the user wants to return to the Tasks List screen without creating any tasks, they simply have to drag the
screen down (Figure 1-12).
Figure 1-12 Add Task screen

App Development

Before we start working with the different architectures in the next chapters, let’s first see how to prepare the ap-
plication for it.

Technologies Used

For the development of this application with each of the architectures, Xcode 13.3 and Swift 5.6 have been used.

The database used is Apple’s own Core Data, and the views and navigation between them have been developed di-
rectly with code, without using .xib or .storyboard files.

How to Remove Storyboard Dependence

To develop the application (with the different architectures) without using a storyboard, we have to do the
following:

First of all, we open Xcode and select the Create a new Xcode project option (Figure 1-13).
• First of all, we open Xcode and select the Create a new Xcode project option (Figure 1-13).

Figure 1-13 Welcome to Xcode screen

• Next, we select the App template in iOS (Figure 1-14).

Figure 1-14 App template selection screen

• The next step is to indicate the name of the application (Product Name), select the development team and
the organization identifier, and choose Storyboard as the interface, Swift as the language, and Include Tests
(Figure 1-15).
Figure 1-15 Choose project options screen

• After creating the project, its configuration screen will appear. On this screen we must remove the “Main”
option in the Deployment Info ➤ Main Interface section (Figure 1-16).

Figure 1-16 Project configuration screen

• Then we delete the Main.storyboard file (Figure 1-17).


Figure 1-17 Remove Main.storyboard

• Finally, we access the Info.plist file, display its content, and remove the Storyboard Name line: Information
Property List ➤ Application Scene Manifest ➤ Scene Configuration ➤ Application Session Role ➤ Item 0 ➤
Storyboard Name (Figure 1-18).

Figure 1-18 Remove storyboard reference from Info.plist

• When working with a storyboard, the window property is automatically initialized and the root view con-
troller is set as the initial view controller in the storyboard. When removing the storyboard, we will have to do it
ourselves.

This is done in the SceneDelegate.swift file, modifying the content of the function

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else {
return
}
}
}

by this code (this part of the code can be modified depending on the needs of our application):

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = ViewController()
window.makeKeyAndVisible()
self.window = window
}
}

Core Data Configuration

In this application we will use Apple’s database, Core Data, but we have not selected it when setting up the project
so that we can use our own database management class.

How to Create Database and Entities

To do this we will start by creating the database model and its entities:

• In the main menu of Xcode, we select File ➤ New ➤ File…. In the templates menu that appears, descend to the
Core Data section and select Data Model (Figure 1-19).
• Next, we give the file a name (in this case ToDoList) and create it (Figure 1-20).

Figure 1-19 Select Data Model file template


Figure 1-20 Create a Data Model file

• Now we are going to create the entities that we will use in the application, TasksList, and Task. To do this, we
select the ToDoList.xcdatamodeld file and add the two entities mentioned with the properties shown in Figure
1-21 and Figure 1-22.

Figure 1-21 Creation of the TasksList entity

You might also like