0% found this document useful (0 votes)
103 views49 pages

E-Book - iOS Apps Architectures For Large Scale Projects

This e-book by Aleksa Simić explores iOS app architectures suitable for large-scale projects, providing practical examples from apps with over 60 million users. It covers various architectural patterns such as MVC, MVVM, VIPER, and The Composable Architecture, emphasizing their scalability, maintainability, and testability. The goal is to equip readers with the knowledge to choose the appropriate architecture for their specific iOS projects based on their unique requirements and constraints.

Uploaded by

Nikhil Sahu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
103 views49 pages

E-Book - iOS Apps Architectures For Large Scale Projects

This e-book by Aleksa Simić explores iOS app architectures suitable for large-scale projects, providing practical examples from apps with over 60 million users. It covers various architectural patterns such as MVC, MVVM, VIPER, and The Composable Architecture, emphasizing their scalability, maintainability, and testability. The goal is to equip readers with the knowledge to choose the appropriate architecture for their specific iOS projects based on their unique requirements and constraints.

Uploaded by

Nikhil Sahu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 49

E-BOOK

iOS apps
architectures for
large scale projects
With practical examples
from iOS apps with 60M+ users

Aleksa Simić
www.aleksasimic.com
iOS apps architectures for large scale projects 01

Table of Contents
Introduction 02

Chapter 1: What is good architecture? Is it a myth? 03

Chapter 2: iOS demo app overview 06

Chapter 3: Everything starts with Networking 09

Chapter 4: Is MVC at scale possible? 15

Chapter 5: MVVM success stories 21

Chapter 6: How to avoid snake bites when using 27


VIPER

Chapter 7: TCA and what large-scale companies are 33


using it?

Chapter 8: Clean architecture + Modularized 41


architecture, overkill or not?

Conclusion
47

www.aleksasimic.com
iOS apps architectures for large scale projects 02

NICE TO MEET YOU!

Hi! I'm Your Coach


Aleksa Simic
Why am I a relevant person to write this course?

I started my iOS career in 2017, while I was still at college,


and ever since then, I have lived and breathed iOS. During the
last 7 years, I had a chance to travel the journey of working in
product-oriented companies, completely outsourcing
companies where I worked on multiple iOS apps
simultaneously each day, working as an iOS consultant for
many large companies, and finally, for the last two years, I am
running my mobile development agency.

Simply put, that variety of experiences helped me to try out


many different things and see practical examples of whether
they work or not.

I had a chance to work on many different technologies,


starting from Objective-C then transitioning to Swift and
UIKit, and finally, SwiftUI (from the moment it came out).
Those are all tools, but my real passion has always been iOS
app architecture and system design.

That’s the reason why on each iOS project I was ever involved
with, I always wanted to try out the new architecture and
optimize things further to reduce build times, and app size, as
well as improve developer experience.

I tried out architectures like MVC, which was the first iOS
architecture I ever tried out, then MVVM, VIPER, The
Composable Architecture, and MVVM + Clean architecture +
Modularized architecture on an iOS app with over 60M users.

Through this e-book, I will, through practical examples, give


you insights into how every single one of this architecture
works at scale. The goal of this e-book is that, after you finish
it, you will understand these architectures in depth and how
big iOS apps that are using them work. Also, you will be able I devote this book to Tijana Spasic, who has
been my support trough every important
to determine how and which of these architectures you can journey I had in my life, including this one.
use in your iOS projects.

Enjoy the journey! — Aleksa


iOS apps architectures for large scale projects 03

CHAPTER ONE

What is a “perfect”
iOS architecture? Is
that a myth?
To be completely honest with you, that’s the question I’ve been searching for an answer to for
the past 5 years.

And I am ready to share it all with you through this e-book.

So to begin, I tried to ask myself, what qualities should the “perfect” iOS architecture have?
After thinking about it thoroughly, I singled out the following eight qualities “perfect” iOS
architecture should have, in my opinion:

1. Scalability - it should be able to scale infinitely and no major issues should happen once we
start adding more features or modularizing our app both vertically or horizontally.
2. Maintainability - adding new features shouldn’t break the rest of the app. If it does, the
minimum effort should be enough to fix it.
3. Testability - if we write unit tests, we should be able to get the test coverage up to 90%.
4. Easy to work with - all of the team members should be able to easily work with the
architecture setup regardless of their seniority in the technology. Also, onboarding new
developers to the project should be frictionless and within 1 week they should be able to
add new code to the project.
5. Clear separation of concerns - the distinction between UI, Business logic, and Data layer
should be clear, but the setup shouldn’t be complicated or hard to understand.
6. Ideally, not dependent on any third-party SDK - I found this out the hard way on one of our
projects, but more on that in the upcoming chapters.
7. Performance - when the app scales, build times should stay fairly small.
8. App size - the app shouldn’t grow much in size when using this architecture once the app
scales.

www.aleksasimic.com
iOS apps architectures for large scale projects 04

I completely agree that there are maybe a lot more items to be added to this list, and maybe
some of them can be stripped off the list, but my 2 years of research on this topic led me to this
list, so for every architecture I analyze in this e-book, I will go through some of these things and
try to treat them as benchmarks based on my previous experience working with them.

Is there a “silver bullet” or “perfect” architecture for your iOS app that aligns with all of the
eight points above? Probably not.

There’s only the perfect architecture for that particular iOS project you are building. Each iOS
project has its own set of rules, boundaries, scale, and the business problem it should solve. By
the time you finish reading this e-book, you should be able to determine what the “perfect”
architecture for your current iOS project you are working on is, as well as determine it for the
next iOS project you will start working on, as soon as you receive the business requirements
from the clients.

Until we dive deeper into architectures, I have a couple of questions you should ask yourself
each time you are thinking about the “perfect” iOS architecture for any project you are working
on:

1.How much the app will scale?

This is probably the number one thing you should be thinking about when deciding about which
architecture to pick. I think of every single iOS app I work on as if it is going to scale infinitely
and have millions of users, and make my decisions based on that. However, the architectural
choice should probably be different if you are making an internal app for some company that
only their employees will use, and when you build an app that will be completely open, for which
you expect to have a lot of users. In the first scenario, you would probably want to go with the
architecture which is simple, easier to maintain, and doesn’t have many components across the
app layers. In the second scenario, however, you would probably go with the scalable
architecture, which has many more layers in its system design, is completely testable, and
maintainable.

2.How much time do you have to deliver new features?

The working environment is a huge factor when picking the architecture. From my previous
experience, people usually tend to forget this factor when they make this kind of decision but it
is just so important. Are you building an app for yourself, working in a company, or working as a
contractor? How tight are the deadlines? Do you expect to constantly be under pressure to
deliver, or not? These are all of the questions you must know the answer to. If you expect that
you will constantly need to work under some kind of pressure and you will always be chasing
some deadlines, then probably you want to go with a simpler architecture, probably use SwiftUI
to boost the development speed, but not take much into consideration how testable and
scalable your architecture is, at least in the beginning. However, if expect you will be working in
a slow-paced environment, where you will work be working at your own pace, looking in the
long run, it will probably be better if you go with something which has more business layers, is
more stable, and provides higher testability than the one from the first scenario.

www.aleksasimic.com
iOS apps architectures for large scale projects 05

3.How big will the development team be?

Will it make much difference if you are the only one working on the project or you will be
working on the project with 15 other iOS developers? Well, probably yes. If you will be the only
developer, you should probably keep things simple and move fast, and that’s why you should
pick the architecture that has those two qualities. On the other side, if you will be working with
15 other iOS developers you probably want to pick something more maintainable and scalable.

4.What business problem are you solving?

Many people overlook this and think their architectural choices shouldn’t depend on the
business problems or the industry the app is in, but actually, it’s quite the opposite. Your choice
will indeed be different if you are building something for a company like NASA, or a small
startup company, right? That’s one more reason I believe the iOS engineers should pay much
more attention to what business problems they are solving, and not only how will they write
their code, usually these two are much more connected than people think.

Now, after we asked ourselves these questions, let’s start building and diving deeper into iOS
app architectures and system design 🚀

www.aleksasimic.com
iOS apps architectures for large scale projects 06

CHAPTER TWO

iOS demo app


overview
When I started writing this e-book, one of my main concerns was how to write about the
architectural patterns, which end up being some pieces of code, without actually spending too
much time talking and explaining the code, and spend more time talking and explaining my
experiences with all of these architectures in large scale apps.

After giving it quite a lot of thought, I decided to go with something in the middle. That means
that I have decided, for this e-book, to create one simple demo iOS project, which will be a
showcase and comparison of the following four architectures we will be discussing in this book:
MVC, MVVM, TCA, VIPER, and modularized MVVM.

Also, I wanted to make that demo project as simple as it gets, to focus more on sharing the
experiences, as I previously said. That’s why I decided for the demo project to have a minimal
set of functionalities that are present in almost all iOS apps and those are:

1. Fetch some data from the API


2. Display a loading indicator while the data is being fetched
3. Display the data in the list of elements on the UI

Pretty easy, right?

For a better visual representation, this is how the screen with all of the functionalities above
looks like after the data has been loaded from the API and displayed on the UI:

www.aleksasimic.com
iOS apps architectures for large scale projects 07

Figure 1. Visual representation of how the first screen of this e-book’s demo iOS looks like

Figure 2. Visual representation of how this e-book’s demo iOS app looks like after data has
been successfully fetched from the remote server
www.aleksasimic.com
iOS apps architectures for large scale projects 08

I implemented this screen alongside the logic in all of the five architectures I will be discussing in
this e-book, and all of the code snippets I will be using, are from that demo project.

For the UI part, in the MVVM, TCA, and modularized MVVM, I have used SwiftUI, and for the
MVC and VIPER, I have used our good old friend UIKit, simply because these architectures
make no sense in SwiftUI, and all of the large scale projects I had a chance to work on in MVC
and VIPER, were written in UIKit.

Based on the comparison of all of these architectures through the code samples, you will be able
to determine and choose the architecture that works the best for your current and all of the
upcoming iOS apps.

Without further ado, let’s start building the only thing that will, alongside models for mapping
data from the API, and some UI elements, be shared amongst all of these architectures in the
demo project, and that’s the networking layer.

www.aleksasimic.com
iOS apps architectures for large scale projects 09

CHAPTER THREE

Everything starts
with Networking
Probably, every app you have ever worked on has communicated to some database to fetch and
persist some data. It’s possible also, that you have worked on an app that is persisting data in
some local database, probably if the app you worked on supported offline mode. In the best-case
scenario, at least from a learning perspective, you have worked on an app that supports both
offline and online modes. Whichever the case might be, storing and fetching data from
somewhere is always the core of an iOS application.

If you are already familiar with everything there’s to networking in iOS, you can skip this chapter
and go to the next one. On the other hand, if you are curious, and think there’s potentially
something more to learn, I encourage you to keep reading.

In this e-book demo app, for simplicity purposes, the networking module only communicates
with the remote server, so there is no offline persistence.

Over the previous years, I have tried a bunch of different ways to communicate with the remote
server. When I started my first junior iOS developer role, I used third-party SDK Alamofire for
that. I remember how, even when using Alamofire, this whole thing about communicating with
the remote server seemed pretty complicated to me. What was even more confusing is that since
we were using just Alamofire wrappers, I wasn’t aware of what was happening under the hood to
have the bigger picture and full context, and you always want that. That’s why, from then on, for
each networking module I have ever designed and worked on from scratch I try to follow the
following three principles:

1. Try to avoid usage of third-party SDK


2. Try to keep it as simple as possible
3. Have a clear separation of concerns

At the start, most of the the networking modules, or API clients, as some people tend to call
them, were relying on dataTask method and were heavily reliant on closures. Probably, some of
the legacy iOS projects that still haven’t migrated to Combine or modern concurrency with
async/await are still using it. I was personally never a fan of closures, it took me forever to
understand how they work initially so I was pretty happy to refactor the code from closures to
something else as soon as I had a chance.

www.aleksasimic.com
iOS apps architectures for large scale projects 10

Later, when Combine came out there was pretty big hype about it, so pretty much every
organization I was involved in at the moment wanted to migrate their API clients to Combine.
While the paradigm and the reactive way of programming Combine has, was a challenge for
many of the people I know, for me, it was pretty easy to adopt it. Why? I banged my head
against the wall while learning RxSwift on my first ever iOS project I had a chance to work on, so
fortunately enough, Combine came in like a breeze for me. Combine is basically like Apple’s
version of RxSwift, and that’s pretty much it.

Then, as Swift introduced modern concurrency and async/await, the hype was even bigger than
when they announced Combine. Why? The simplicity.

By adopting async/await, Apple gave the developers a chance to write async code almost like
they are writing some serial code, it is just so easy to get started with. However, you should be
careful if you are doing it because there’s just so much stuff happening under the hood to allow
such an easy way of using it. When you want to do some complex manipulations that are beyond
the scope of triggering one API call at a time and getting some data back, I would strongly advise
you to dive deeper into modern concurrency to implement it right. Trust me on this one, the
bugs that can come up when using modern concurrency in the wrong way are pretty hard to
debug and even harder to fix. But then, that’s probably a good theme for another e-book.

For this e-book demo iOS app purposes, the networking module has been written using the
modern concurrency approach and async/await.

The open API I have used for the demo app purposes is NASA’s API which you can find here:
https://api.nasa.gov/. To generate an API key, you simply register with your e-mail and that’s it.
If you need any assistance, you can check the readme file attached to the demo project.

I talked about how important separation of concerns is for each networking module, so let me
walk you through the components of this networking module:

1. HTTPMethod enum

www.aleksasimic.com
iOS apps architectures for large scale projects 11

If you did a setup of an API client from scratch before, then this code is probably pretty familiar
to you. If not, this enum is simply used to encapsulate the HTTP method used later when
creating a URLRequest and setting the request httpMethod, so we don’t use plain String, and
use an enum raw value instead. For example:

2. HTTPMethod enum

Again, a fairly simple enum to encapsulate all of the possible errors when communicating to the
remote server.

www.aleksasimic.com
iOS apps architectures for large scale projects 12

3. URLRequestable protocol

This protocol encapsulates all of the information that a single request to the remote server can
have. Then, all of the concrete requests we use in our app, conform to this protocol and just fill
it with the needed information. For example, the only request we will be using in the demo
project is set up the following way:

www.aleksasimic.com
iOS apps architectures for large scale projects 13

4.APIRequestable

This is the main puzzle and the core of the logic for communicating with the remote server. It’s
a remote protocol with the default implementation for creating a URLRequest from the
previously mentioned URLRequestable and sending that request by using the request method
which utilizes modern concurrency and async/await.

www.aleksasimic.com
iOS apps architectures for large scale projects 14

5.NasaPlanetServiceLive client

Here, the NASAPlanetsServiceProtocol is created to showcase that when building iOS apps at
scale, we need to write good unit tests, and to make that possible we should be able to inject
mocked service to our business layer modules to unit test them. That’s why all of the pieces of
the business logic will be injected with the instance of NASAPlanetsServiceProtocol and not
directly with NASAPlanetsServiceLive. NASAPlanetsServiceLive, on the other hand, is the
concrete instance of the protocol that will be injected into our live app and uses createRequest
and request methods from APIRequestable to trigger a request and return the data to the
business layer, and that’s all to it.

Since this networking module will be shared through all of the architectures that are present in
this e-book demo iOS app, it was important for me to make sure that you understand how it
works. Now that you do, it’s time to continue with the first architecture we will cover in this e-
book, Apple’s favorite, Model View Controller.

www.aleksasimic.com
iOS apps architectures for large scale projects 15

CHAPTER FOUR

Is MVC at scale
possible?
“Model View Controller is the preferred architecture for all iOS applications”
- Apple

And this is how it all started. At some point, a lot of years ago, Apple made the statement above
in some of their official documentation, that we should use MVC to build all of our iOS apps.
And all of a sudden, all of the iOS developers around the world started using this architecture
for their iOS apps.

At that time, if I am not mistaken, Swift hadn’t yet been released, so all of the apps were pretty
much written using Objective-C. To be fair, because of that, back then it was quite difficult to
extract the the business logic in a separate layer or do some more advanced code organizations.
What were the results of this?

A very large number of apps, where some of which had super large codebases, were using MVC,
and slowly, step by step, maintaining those kinds of projects became more and more difficult.
Now you are probably wondering why. To answer that question, let’s dive in more deeper into
what MVC is and how it works.

Model View Controller is a widely known architecture, used a lot outside of the iOS ecosystem
also. It has three main components:

1. Model - all of the business logic-related entities you are using in your app
2. View - depending on what technology you are using, it can be SwiftUI view (although I highly
do not recommend even trying anything like MVC with SwiftUI), or any UIKit-related
component like UIViewController, etc. if you are using UIKit
3. Controller - the component that connects models and views and is responsible for all parts
of the business logic and displaying them on the UI. When I think about the Controller part
of MVC, I immediately think of any ViewController I ever encountered through my career,
that is the most relevant example of a view controller that you might bump into

www.aleksasimic.com
iOS apps architectures for large scale projects 16

Now, once we understand what the basic components of the MVC architecture are, let’s see
what those components are in our demo app and how all of them work together in MVC.

1. Model - in our demo app, our model is the only model we are using to map the data we are
fetching from the remote server and that is Astronomy :

2. View - in our demo app the view is represented by a AstronomyListViewControllerMVC xib


file which we are using to render the list of Astronomy objects on the UI, by utilizing UIKit
components like UITableView and UITableViewCell
3. Controller - The controller in our app is AstronomyListViewControllerMVC.swift file which
is connected to AstronomyListViewControllerMVC.xib and has all of the business logic inside,
as well as the logic to display that data on the UI:

www.aleksasimic.com
iOS apps architectures for large scale projects 17

As you can see, it uses and NasaPlanerServiceLive service, explained in detail in Chapter 3,
which sends the request to the remote server and returns it as an array of Astronomy objects.

www.aleksasimic.com
iOS apps architectures for large scale projects 18

Are you thinking what I am thinking? Too much code for a simple functionality like this?

90 lines of code. That’s how big AstronomyListViewControllerMVC.swift is. All it does is fetch
the data from the remote server using NasaPlanerServiceLive and display it on the screen
through tableView.

And that right there is the main problem of MVC. And I am not talking about the number of
lines here, I am talking about everything just being in the same place. Three main things which
are happening on the screen:

1. Fetching data from the API


2. Displaying that data on the UI
3. Filling table view with fetched data
4. Potentially navigating to the next screen when the user taps on one element in the list

And it’s all happening in the same file. Now why is that the problem?

There are a couple of issues with this approach, and I will go through them one by one.

Scalability. MVC architecture is not scalable. Because all of the code resides in just one place,
once your screens and features become more and more complicated, you will soon end with
ViewControllers with massive amounts of code, and that issue is more commonly known as
Massive View Controllers. If I am not mistaken, the largest ViewController I have ever
encountered had around 3000 lines of code. Moreover, when you take into consideration that a
couple of iOS developers will be adding and modifying functionalities on that screen, it becomes
pretty clear that maintaining iOS apps with MVC is pretty hard, mostly when we are talking
about fairly large codebases.

Testability. When using MVC, it is pretty hard to write Unit Tests. Why is that? Again, as we can
see in our example above, the instance of the service which is responsible for the business logic
NasaPlanerServiceLive is inside AstronomyListViewControllerMVC.swift which means that if we
would want to write unit tests for our business logic inside NasaPlanerServiceLive, we would
have to instantiate the whole AstronomyListViewControllerMVC which is pretty hard and
unoptimized. Furthermore, because all of the UI is connected directly to the ViewController, it
is impossible to verify if the pieces of information we are filling the UI with are correct. To be
honest, during my 7 years of iOS career, I never quite saw an MVC iOS app with properly
written unit tests and with high code coverage. To be fair, we could easily write unit tests for our
service NasaPlanerServiceLive in isolation, but as mentioned above, the actual problem comes
when we try to write unit tests for how our service integrates with our view controller and feeds
the information to the UI.

No separation of concerns. All of the code just sitting in one place removes any possibility of
separation of concerns. Want to call an API call? You do it in the view controller. Want to
navigate to the next screen? You do it inside the view controller. You get where I am going with
it.

What are my experiences with MVC architecture?

www.aleksasimic.com
iOS apps architectures for large scale projects 19

When I talk about my experiences with MVC, I love to talk about two different situations, one of
which happened at the early stage of my career, and the other one which happened recently, in
the later part of my career.

As for the first experience, and my first MVC encounter, it happened on my second ever iOS
job. At that time, I moved from a completely product-oriented company where I worked for
about a year, to a fully outsourcing company where I had a chance to work on many different
iOS projects. Moreover, I moved from an environment where the code I worked on was using
MVVM architecture in combination with RxSwift to an environment where all of the projects are
written with MVC. When I looked at MVC code at first, after MVVM and RxSwift, I was like, oh
my god this is so much easier, I will have no issues with this codebase and I will be able to add
features and modify the existing code easily. Pretty soon, after just a couple of months, I
realized I was never so wrong in my life. Because the app was pretty large, it was for one large
client for which the company has been working for 5 years, the view controllers which were the
core of the app functionality were all 1500+ lines of code. Also, because of the MVC, there were
no proper unit tests in that project. That’s why, whenever I added or modified some pieces of
the code, no matter how careful I was, I ended up introducing a bunch of regression bugs which
then I would fix and introduce new bugs and I felt like I was pretty much running in circles. At
some point, I raised that concern to my iOS team leader at the moment, so we sat and discussed
how we could improve the processes and the codebase. After a couple of hours, the best we
could come up with since we didn’t have the time allocated from the clients to migrate the
codebase slowly to some different architecture approach, was to extract the pieces of core
functionalities to a separate component. For example, because the app was supplier/venue
management we had a bunch of stuff on the UI dependent on the state of the order. That
resulted in a bunch of difficult switch cases and if statements across the whole view controller.
So we took all of those pieces of business logic and extracted them outside of the view controller
to a separate component called OrderStatusManager which drove and generated all of the
things needed to be reflected and connected to the UI. Also, we added some pretty heavy unit
tests for the OrderStatusManager where we covered all of the possible order statuses and all of
the possible scenarios. How did that affect the overall project state? Immensely. The number of
regression bugs has been reduced by about 70% per sprint and everybody was pretty happy
about it. But we never quite managed to lower that number even further without moving to a
completely different architecture.

As for the second experience, it happened recently, at the later stage of my career, when I
already had a chance and a privilege to work on many different codebases with many different
technologies. In short, I was much more experienced and versatile in iOS than when I previously
encountered MVC architecture. I just onboarded to a new exciting iOS project, an app used by
60M users worldwide, and I was pretty excited about it. Because it was an app that was on the
AppStore for quite some time now, the codebase was pretty large and had a little bit of
everything in it, Objective-C, UIKit, and SwiftUI. The code which was written in Objective-C was
written by using the MVC approach. Also, I immediately noticed how much attention is the team
spending to keep up with the latest stack, where all of the new stuff was written in SwiftUI and
leveraging modern concurrency using async/await. Also, the same amount of attention was
being spent to migrate the Objective-C code and approach to more of an MVVM approach. How
did we do it?

www.aleksasimic.com
iOS apps architectures for large scale projects 20

In the initial iteration, for all of the Objective-C screens, we would create Swift view models,
extract all of the business logic from the Objective-C view controllers to the newly created view
models, and just leave a reference to the view model in the view controller. Then, in the second
iteration, when we had bigger chunks of time, we migrated the UI code from xibs to SwiftUI. And
because the codebase is that big, that’s an ongoing process that is still happening.

To sum things up, based on my previous hands-on experiences with MVC in a couple of
different situations, and large-scale projects, I would say that MVC can be a good architecture
to start your iOS development journey. But if you want to build a scalable app, you definitely
should consider using a different architectural approach.

Good thing I got them all covered in this e-book for you!

www.aleksasimic.com
iOS apps architectures for large scale projects 21

CHAPTER FIVE

MVVM success
stories
The next architecture we will cover in this book, Model View ViewModel, came to address all of
the problems that MVC had.

Let’s start by breaking down all of the components MVVM has:

1. Model - represents all of the business logic entities we are using in our iOS app. In terms of
this book demo app, the model layer is the same as in the MVC and is presented with the
Astronomy struct which holds all of the information about the Astronomy object we want to
fetch from the remote server and display on the UI.
2. View - similar to what’s happening in MVC, the View component represents the UI that is
displayed in our iOS app. In the MVVM, depending if you are using UIKit or SwiftUI, the
View component is UIViewController or SwiftUI View. When talking about the example in
our demo app for this e-book, the View component is represented with the
AstronomyListMVVMScreen:
iOS apps architectures for large scale projects 22

As you can see, unlike the MVC, the View layer in the MVVM architecture serves only as a
binding layer between the view model and the UI and doesn’t have any unnecessary business
logic as in the MVC.

For example, the View layer in the MVC example from Chapter 2,
AstronomyListViewControllerMVC, has 96 lines of code, while in the MVVM example, the
View layer AstronomyListMVVMScreen has only 50 lines of code.

www.aleksasimic.com
iOS apps architectures for large scale projects 23

Again, I would like to say that the purpose of the MVVM architecture is not only in reducing
the number of codes in the View layer, but is instead the clear separation of concerns, moving
all of the business logic-related things in the view model, and making the View layer as
dumbest as possible.

3. ViewModel - the layer in the MVVM architecture that is responsible for encapsulating all of
the business logic-related things:

www.aleksasimic.com
iOS apps architectures for large scale projects 24

As you can see from the code example above, the view model's purpose, is usually, to
encapsulate the following four things:

1. Communication with remote servers or local persistence through services


2. Do data manipulations needed for data be properly displayed on the UI
3. Handle all of the actions from the View layer coming from the user interaction with the
app
4. Handle navigation between screens in your app, or delegate the handling further to some
order component you use for navigation (ex. Coordinator)

If we now go back to the things from Chapter 1 which I mentioned are necessary for a “perfect”
iOS app architecture to have, we can see that MVVM architecture meets all of those standards:

1. Scalability - with MVVM, scalability is pretty straightforward because if you have a view
model for each of the screen and component in your system, as MVVM suggests, you will
end up having views that are simple, “dumb”, and small, and view models which are
responsible for everything non-UI related. So whenever you want to scale your app and add
new views, or modify existing ones, you just need to follow MVVM principles, and you
should be able to scale your app indefinitely. If you are adding a new view, you should
create a view model to encapsulate all of the business logic needed for that view. Also, if you
are modifying existing components, just place the new functionality in the view model if it is
business logic related and keep the separation of concerns clear, and you shouldn’t have
any bigger problems scaling an app with MVVM.
2. Maintainability - while maintainability in the MVC can be hard, because you put all of your
code in one place, with MVVM having a clear separation of concerns, maintainability also
relies on just putting the code in the correct place in the MVVM architecture, and that’s it,
you’ll keep the maintainability as your project grows. When you introduce and modify new
things, even if some unexpected regression bug occurs, you will be able to more easily track
it down and fix it because the UI and the business logic are separated, and based on the bug,
you will know where to start debugging from. Absolutely the same thing goes with
maintainability when adding new functionalities in your app.
3. Testability - testability is one more big advantage of MVVM over MVC. As I said in Chapter
4, writing tests in MVC is hard because you would need to instantiate a whole view
controller to write proper unit tests for the pieces of your business logic. On the other hand,
with MVVM, you can easily write unit tests for business logic because it’s now in a separate
layer, and instead of having to instantiate the whole view controller to write good unit tests,
you need to instantiate only view model, fill it with mocked services instead of the live,
production, ones, and write your unit tests. Much better, isn’t it?
4. Easy to work with - while many people don’t pay much attention to this point, I believe it is
truly vital from both the product perspective and the development team perspective. When
it comes to MVVM, if used properly, with a set of clear rules inside the development team
on how each view model should be written, to keep some consistency across the team,
MVVM is really easy to work with, doesn’t have a steep learning curve like, for example,
TCA has and onboarding new team members, even juniors, is pretty easy.

What are my experiences with it?

www.aleksasimic.com
iOS apps architectures for large scale projects 25

My first introduction to MVVM was on my first ever iOS job in a product-oriented company,
which I mentioned in the previous chapter, where we worked on developing our multi-banking
solution.

Coming straight from the faculty, my experience with mobile apps until then was on a pretty
basic level. I have developed a couple of Android apps for faculty purposes. I remember my
favorite one is a ride-sharing application we called “RideAlong” (there was no ChatGPT at the
time, so we came up with this on our own), intended for users to share transportation to school
or work, and by doing that, minimize their gas expenses. It was so much fun working on this, we
even implemented a GoogleMaps integration which would draw the most optimal route, and live
chat between the participants on the ride implemented from scratch on socket technology. We
had some difficulties when demoing it since we pulled up an all-nighter the night before to
manage to finish it on time, but it was that particular experience that made me decide that I
wanted to pursue a career in mobile development.

Now coming back to MVVM and my first ever iOS job. Obviously, in the previously mentioned
faculty project, we didn’t pay much attention to the architecture, we didn’t have the time or
knowledge to do it. That’s why, when I first saw MVVM on that project, plus the fact that the
view models were using RxSwift for fetching the data from the remote servers and preparing it
for the UI, I kinda freaked out. Also, I remember we used a pretty specific setup in that project
where one view model was being instantiated from two different places, where on each of these
places you fill it with some set of properties. At that time, I was like, oh my god what’s
happening here?

After that initial feeling of confusion, when I sat down with my first-ever iOS mentor (Nikola,
kudos to you) and he explained the whole flow, I figured out it’s not that scary after all. During
my first three months of working there, I worked on an internal app from scratch, to get
familiarized with the MVVM and RxSwift, which was pretty great and beneficial for me.

After that first three months, I joined the main product team, and alongside 4 other iOS
developers, 2 in-house and 2 working remotely, started contributing to the codebase. It didn’t
take me too much time to figure out how good MVVM works at scale.

We had a pretty strong set of ground rules of how our view models should look like, what
functionalities should they have, and how they should prepare the data for the UI, so adding
new screens in the app ended up pretty much just having to follow that set of rules, and
everything ends up functioning perfectly. We were a team of 5 iOS engineers, contributing to a
pretty large codebase, and we ended up each sprint with a maximum of one to two regression
tickets to tackle.

My second experience with MVVM I would like to share with all of you here is when I joined a
team of 20 iOS engineers to work on and contribute to an iOS app with over 60M users on the
iOS platform.

When I was first joining the team, I thought to myself, I can’t wait to see what tech stack they
are using on a project which is of that large scale. I was really curious to see if there is some kind
of a super fancy architecture made up entirely for large iOS apps, which I have been missing out
on all of this time. And then I saw it, it was all MVVM.
www.aleksasimic.com
iOS apps architectures for large scale projects 26

That large of an app, working entirely on MVVM, I was thinking to myself there must be
something to it, it can’t be that simple. But it was. To be fair, everything was layered even
further, into clean architecture and modules, which I will cover in much more detail in Chapter
8 of this e-book, but in the end, everything was driven from the MVVM architecture. I was
amazed at what MVVM, within a good organization, with a good set of ground rules, can
achieve.

Simplicity is the key. After the onboarding process, when I started to actively contribute to the
codebase and was getting my pull requests reviewed for the first time, I figured out something
that I kind of knew all the way along, large-scale software’s codebases need to be as simple as it
gets. Just imagine having a team of 20 iOS engineers continuously contributing to the codebase
and writing functions in the view models in a way that every function needs a detailed comment
for the next developer to be able to understand how it works. That’s when I realized, if you want
MVVM which scales great within big organizations, just keep your code in view models as simple
as possible, and that’s pretty much it.

As that app continues to grow, the team doesn’t have any ambition to ditch the MVVM and
move to some other architecture, and that’s the decision purely based on how well MVVM
worked for them so far. The only thing they are focusing on is moving more code that is not
under MVVM at the moment to MVVM because it is an app that has been around for quite some
time and some of the code has been written years ago, and that’s it. MVVM will stay at the core
of their large-scale iOS app.

iOS apps written on MVVM architecture sure can scale more than well. However, the important
things when using MVVM in large-scale projects and organizations are:

1. Keep things inside MVVM as simple as you can


2. Have a good set of ground rules on how you write view models, to keep consistency across
the codebase

If you live up to these two, you can use just MVVM to scale your iOS app indefinitely.

www.aleksasimic.com
iOS apps architectures for large scale projects 27

CHAPTER SIX

How to avoid snake


bites when using
VIPER
VIPER architecture in iOS, at least for me, is one of the most challenging and complicated
architectures I have ever encountered.
That’s why, I will try to simplify things as much as I can for all of you reading this, and cover
each of the layer in the VIPER architecture through the practical examples from this e-book
demo app:
1. View - Similar to MVC, and MVVM, this is a layer of the VIPER architecture that is
responsible for the UI layer, usually ViewController, or if you are very enthusiastic and want
to use VIPER with SwiftUI, a View. What’s different for this layer when compared to MVC
and MVVM, is that usually, it’s defined with a protocol to which ViewController or View
conforms. That protocol defines a set of functions needed which View will do to update the
UI once some data from the Presenter is emitted, for example when it’s fetched from the
remote server. Then, the Presenter layer has a reference to the View protocol, and it calls
its function to send the data to the UI layer.
All of the communication the View layer has with the outside world goes through the
Presenter component, as you can see from the following code snippet:

www.aleksasimic.com
iOS apps architectures for large scale projects 28

2. Interactor - The interactor is a layer that is responsible for two different types of
interactions, and therefore, it’s usually implemented through two separate protocols:
a. Interactor - The interactor is a layer that is responsible for two different types of
interactions, and therefore, it’s usually implemented through two separate protocols:
Input interactions - a set of actions that are passed from the View to the Presenter layer.
Then, the Presenter delegates the execution to the input interactions protocol. In the
demo example, the example of that interaction would be fetching data from the remote
server when the View loads.

Further, the concrete implementation of the astronomy list interactor conforms to the
input interaction protocol, implements the protocol functions, and uses a service to fetch
data from the remote server.

After the data is fetched, the interactor, by using the output interactor protocol, moves
that data further to the View.

www.aleksasimic.com
iOS apps architectures for large scale projects 29

b. Output interactions - a set of actions that are used to move the data fetched from the
remote server, through interactor output, back to the view.

As you see from the example above, this a set of functions that happens after some data
has been fetched from the remote server, and the Presenter implementation conforms to
the interactor output protocol, and moves the data further to the View layer:

3. Presenter
In my personal opinion, this is the core component of the VIPER architecture.

I think that simply because it’s the main communication point between the View layer and
the rest of the VIPER architecture layers, and just delegates the responsibilities.

As we can see from the example below, it’s also defined through a protocol that consists a
set of actions that the View will be sending towards the Presenter.

The concrete implementation of the protocol has the reference to the view to be able to
move data updates back towards the view by conforming to InteractorOutputVIPER, as
we see above.

Also, it has a reference to the Router layer, to handle some navigation actions sent from
the View layer.

The final reference it has, is the reference to the Interactor layer, to trigger business-logic
related things, such as, for example, fetching data from the remote server.

You can check the whole Presenter layer implementation here:

www.aleksasimic.com
iOS apps architectures for large scale projects 30

You can check the whole Presenter layer implementation here:

4. Router - the layer of the VIPER architecture responsible for everything regarding the
navigation. If you previously used the Coordinator pattern, it’s something pretty similar to
that.
The presenter layer has a reference to the Router layer, and then, once some action that
requires any navigation-related logic is sent from the View to the Presenter, the Presenter
sends it to the Router.

www.aleksasimic.com
iOS apps architectures for large scale projects 31

5. Entity - Similar to Model in MVC and MVVM, Entity has all of the models needed both
for the business logic and the UI in the VIPER architecture. To avoid repetition, I won’t post
the model again here, but it’s in the Astronomy.swift file in the demo app.

Looks complicated already? Imagine having all of these layers in a large-scale app and having to
change something and introduce some updates.

What are my experiences with it?

I had just one hands-on experience with VIPER architecture and I want to share it with you
entirely.

So at one point, about a year ago, a client came to us with the request to continue with
maintenance and feature updates of their iOS and Android apps. Usually, in that kind of
scenario, I like to take a look at the codebase first, before deciding whether we will be taking
over the project ourselves or not.

That’s what I did that time also, and saw the whole iOS project they had was written in VIPER.
On the other hand, the project was pretty small at the time, and the app idea was pretty
interesting, so in the end, I decided to accept the project.

Their initial request for us was to change a couple of things in the functionalities and submit the
app for release on the AppStore. At first, the set of updates seemed pretty similar, so we gave
an estimation of two weeks to introduce the needed updates.

Then, when we started working, we soon realized that probably the two-week deadline wouldn’t
be enough to make all of the updates. Why? Well simply put, every change in the app when you
are using app architecture needs to be propagated through all of the VIPER layers to work
properly, and because of that, the process is taking much more time than usual.

Since we didn’t have to rewrite the app at that time, we introduced the needed updates in the
existing VIPER architecture and submitted the App to the AppStore. Just it took us one month,
instead of the initially estimated two weeks, but the clients understood the situation and why
that happened, so everything went okay.

Right after that, we decided to rewrite the whole app, while it’s still smaller, to something more
easier to maintain and faster to develop, so we decided to go with MVVM + Clean architecture +
Modularization of the whole project. It turns out that was a really good decision, and more
importantly, very good timing for making the decision.

I am saying that because we are still working on that project and all of the updates and new
features we introduced in the meantime were so huge the app is now a minimum triple the size
it was initially. Introducing those updates with VIPER would be pretty hard, and time-
consuming.

www.aleksasimic.com
iOS apps architectures for large scale projects 32

After this experience, I never felt like VIPER could be a good solution for us to build fast and
scalable apps.

Probably, there are some use cases when VIPER can indeed be useful, but if you want to achieve
the mentioned two things, then VIPER probably isn’t a good architectural choice for you.

www.aleksasimic.com
iOS apps architectures for large scale projects 33

CHAPTER SEVEN

TCA and what large


scale companies are
using it?
When Apple introduced SwiftUI and as people started adopting it and getting used to it, a bunch
of different architectures started emerging.

The initial go-to architecture that everyone started using for their iOS projects was, previously
mentioned, MVVM. While there’s an ongoing debate whether SwiftUI should work with MVVM
or maybe just MV, without view models, the fact is that most of the apps that adopted SwiftUI
from the moment it came out, are using MVVM.

I remember the day when SwiftUI came out, I was so enthusiastic about it that I pretty much
every day asked my iOS team leader if we could start using SwiftUI for a new project that we
were about to start. He kept saying to me that SwiftUI isn’t ready for the design the app should
have and that it is just not stable yet. Even though I tried elaborating that we have
UIViewRepresentable and UIViewControllerRepresentable and that we can fall back to UIKit
whenever we feel like that component is not deliverable in SwiftUI, we ended up starting the
project and delivered the MVP app with UIKit and MVVM.

However, that didn’t stop me from jumping into SwiftUI right away. At that moment, I was still
at college, finishing my Computer Science master studies, and we had a home project where we
had to deliver an app in any of the newest technologies and compare it to the previous
technology used for that tech stack. As you might have guessed, I have picked SwiftUI and used
it to build an app that enabled users, by using ARKit, to see how a piece of furniture would look
in their room, by placing it wherever they like. Something similar to what IKEA has now, but
much much simpler.

I can’t say exactly that I am proud of the code I have written, but everything worked pretty well,
and that was the moment when I figured out that SwiftUI was something I wanted to focus on.
Even though a lot of people were pretty skeptical about it in the early days, and were talking
about UIKit is UIKit, if we see the bigger picture now, and the fact that 90% of the job posts
require some SwiftUI experience, I think I made the good call.

www.aleksasimic.com
iOS apps architectures for large scale projects 34

Right after that, I dived into contract iOS work roles, and my first contract role was rewriting
one of the largest Switzerland weather apps from UIKit to SwiftUI. There, under the hand of a
pretty experienced staff iOS engineer, Marko (kudos to Marko), who was leading the whole
process, we managed to move the whole iOS app which had some pretty complex UI, like live
forecasts, cameras, and many more, to SwiftUI. It took me 3 days to move a simple login screen
with a background image and two buttons from UIKit to SwiftUI, but it was there when I
realized, that SwiftUI is ready for production, if you use it properly.

Ever since that moment, I worked on many different large-scale iOS SwiftUI apps and was
responsible for the architectural decisions on quite a lot of them, and I can say that most of
them were successfully using MVVM.

Then, at some point, I started reading about The Composable Architecture, and to be quite
honest, I was so impressed with how the team at Point Free completely shifted the perspective
of iOS app architecture, switching the paradigm from functional programming to Reactive
programming and Redux-like structure.

I want to start by stating that the TCA is a pretty complex architecture, and there are a lot of
things that are happening under the hood, and components that are already written in the
architecture SDK and the developers just consume it, but I will, on the demo app example, try to
break it down and explain it as simple as possible.

Also, if you are already familiar with web frameworks like React or Angular, I still remember
some of their concepts from the college, then some of the components from the TCA might be
already pretty familiar to you.

These are the main building components of The Composable Architecture:

1. Reducer
Reducers are the main building blocks of TCA. Simply put, instead of view models, which
MVVM architecture uses to hold all of the business logic, TCA does something similar and
extracts all of the business logic in a separate component, just with the addition that these
components should conform to the Reducer protocol.

The Reducer protocol. has three main components that glue all of the TCA functionality
together:
1. State - a structure (struct in Swift) that keeps the current state of the screen
2. Action - set of all possible actions that the view (screen) can send to the reducer (the
business logic component)
3. Reduce function - simply put, it defines how the certain action dispatched from the view
will mutate the state

www.aleksasimic.com
iOS apps architectures for large scale projects 35

In the demo project for this e-book, this component, a piece of business logic responsible
for fetching the list of astronomy objects from the remote server and connecting it to the UI
is the following:

As you can see in the code snippet, reducers have a switch statement for each of the
possible actions that view can send to the reducer component, and define how each and
every single one of them will mutate the state.

www.aleksasimic.com
iOS apps architectures for large scale projects 36

2. State
As shortly explained above, a structure (struct in Swift) that keeps the current state of the
screen.

State has all of the properties which are reflected on the screen, and the whole screen re-
rendering is driven purely by updating the State properties.

Furthermore, because it drives the screen updates in SwiftUI, State needs to conform to
Equatable protocol, so the component knows if any of the properties has actually been
changed and to trigger re-render only in that scenario and optimize the number of screen
re-renders. If you worked with SwiftUI previously, I believe you are pretty much aware how
important optimizing screen re-renders is.

In this e-book’s demo project, the State component is the following:

3. Action
Action component is an enum with all of the possible actions which can be sent from the
view to the reducer (the business logic component).
In the demo project, the Action component is the following:

www.aleksasimic.com
iOS apps architectures for large scale projects 37

4. Store
Store is the TCA component which bundles all of the components together and is used
directly in the SwiftUI view.

Through store, SwiftUI view can access the State properties and display them on the UI, as
well as send Actions to the reducer and trigger things like API calls or navigation changes.

As you can see from the TCA example, it has a pretty strongly defined structure. Which is, from
one perspective, pretty cool, because once you adopt in your iOS app, the code will be
consistent across the whole codebase. On the other hand, if you want to do something which is
not aligned with the TCA way of doing things, and let’s say breaks their structural pattern just a
little bit, you might end up having a really hard time trying to do it. I’ve tried it once, didn’t end
well. Will share more details about once you get to the part where I cover my experiences
working with TCA, in this chapter.

www.aleksasimic.com
iOS apps architectures for large scale projects 38

Also, as you probably see, if you are familiar and have previous experience with MVVM
architecture in iOS and have some overall understanding of Redux, you will probably have a
slightly easier time adopting TCA. I am saying this because from one side, it’s kind of a similar to
MVVM, because you have one component, Reducer, which is responsible for the whole business
logic and is the one driving the UI layer, like view model is in the MVVM. On the other side, it
has some Redux like elements, State and Action, which works excellent with the declarative way
in which SwiftUI works. Also, be sure to check out Chapter 8, to see how I created a hybrid iOS
app architecture, by taking best from the both worlds of TCA and MVVM.

One small note for all of you to keep in mind, in the demo app from which the code samples
above are, I have used the TCA version 1.9.3, and in the moment of releasing this e-book, the
current version of TCA is 1.10.2 so there might be some minor updates needed if you would
want to run it with the latest TCA version. The thing which is not so great about TCA is that it is
a third party SDK, and it’s moving so quickly. From one perspective, it’s great that they are
constantly updating their libraries and improving performances, but it can be pretty tricky to
keep up with using the latest TCA version, mostly if you are using TCA in a large scale project.
But we’ll get to that, more in detail, pretty soon in this chapter.

What big companies are using it?

I believe definitely the largest company using The Composable Architecture on a large scale iOS
product is The Browser Company, on their browser named Arc. When I first started thinking
about TCA and whether we should give it a shot or not, one of the first things I Googled was if
some big companies are already using it and when I saw that The Browser Company is, that was
a big green flag for me that we should give it a chance also.

One more interesting fact about The Browser Company, is that they took everything a step
further, and built their Windows application with Swift. Yeah, you heard that right. It is the first
ever Windows application written with Swift, and they said their Windows app shares 80% of the
codebase with their macOS app. How crazy is that?

You can check out more details about how they did it on my detailed article about it I’ve written
for LinkedIn: https://www.linkedin.com/posts/aleksa-simic-10bba5182_github-
thebrowsercompanyswift-winrt-swift-activity-7192228928399310848-N_zi?
utm_source=share&utm_medium=member_desktop.

There a couple of other big companies that I am aware of that are using The Composable
Architecture like crypto.com, New York Times app for kids, Tokopedia, and a couple of more
big companies in the iOS eco space also. You can check out the TCA showcase on their official
GitHub account: https://github.com/pointfreeco/swift-composable-
architecture/discussions/1145.

www.aleksasimic.com
iOS apps architectures for large scale projects 39

What I think is the number one reason of those big companies adopting TCA is defined
structure, consistency, and testability. Imagine running an app with an iOS team of over 30
people constantly contributing to the project, those three things are a must have. If you purely
adopt only MVVM, without any guidelines, then every iOS engineer could write their view model
in a way they prefer. TCA provides that guidelines out of the box by just providing each business
logic component to the Reducer protocol. When it comes to testability, it is one of the strongest
points TCA architecture has, because with using their dependency injection framework: swift-
dependencies in combination with their TestStore component, you can pretty much cover all of
the vital parts of the business logic with unit tests. That’s a theme for another course about unit
testing which I am currently making, but in the meantime, you can check out the basics of unit
testing in TCA in their official docs: https://pointfreeco.github.io/swift-composable-
architecture/main/tutorials/composablearchitecture/01-03-testingyourfeature/

What are my experiences with The Composable Architecture?

As I mentioned above, as soon as I got interested in TCA architecture, and saw that The Browser
Company is using, I decided to give it a shot and try it out in one of the iOS apps we are working
on in my mobile development agency.

At that time, a new iOS engineer joined our team. He was a junior iOS developer, with a previous
experience of couple of years working as a backend developer, but he had no experience in
developing iOS apps. After he went through 100 days of hacking with Swift by one and only Paul
Hudson, which as a must for all of the fresh iOS developers who join my digital agency, I thought
that it would be the best to learn on some real iOS app, then to keep browsing through tutorials
and some demo applications. At the same time, we were supposed to start working on an app
which streamlines the party organization process for it’s users (shameless self promotion:
https://hooray-app.com/) and I thought it would be great if we could try out TCA on that
application and learn together, as a team, through the development process.

We went through all of the available documentation about TCA online, and started working.
First thing I realized immediately was the learning curve. And I am not only talking for our junior
iOS engineer who was working on the project, I am talking also from my perspective. Every time
he reach out to me for help, I needed to revisit their docs, figure out how things work under the
hood, and then provide him with the help he needed.

Then, after a first couple of months with TCA, when we overcome the learning curve, everything
started going pretty fast and smooth. We were delivering feature after feature, not missing a
single deadline.

But after about 1 year into the project, as we kept adding the functionalities and the codebase
grew, we started to notice our build times increasing quite a bit. To be fair, we did a set of
updates advised by PointFree team to optimize build times and it helped, it reduced the build
time by a fair amount, but it was still pretty big.

www.aleksasimic.com
iOS apps architectures for large scale projects 40

Also, we started experiencing issues when we wanted to implement some custom behavior,
which is not following all of the TCA structure and principles, we had a first situation like that
when we wanted to implement navigating to a certain screen and triggering all of the needed
actions when the user opens an app from the push notification. And then we experienced the
similar scenario with a couple of other features also.

Those things eventually led me to make a call to start falling back to the MVVM for some of the
modules we have in the app. And it actually helped us increase developer productivity, while
decreasing build times and enabling us to get the full control over the project again. Currently,
that project is a mixture of TCA in some of the modules and MVVM in other, but we are still
working towards a complete migration to MVVM.

To be honest, after I made the decision to start with the migration to MVVM, I wasn’t 100% sure
that I am making the right call, because I was pretty aware of how powerful and scalable TCA is.
Then, couple of days ago, I bumped into an article from Rod Schmidt, where shared his
experience after 3 years of heavily working on the TCA in large scale project in his company:

https://rodschmidt.com/posts/composable-architecture-experience/. At that point, I was sure I


made the right call.

Ron actually pointed out that they had a similar set of issues working with TCA we also
encountered and which I shared above:

1. It’s Complicated - It sure is! While we as team enjoyed learning it, we came to an issue that
it was pretty hard to onboard a new team member to grasp the concept of TCA, mostly if he
is another junior iOS developer, and it was one of my concerns from the moment we started
using it.
2. The Churn - TCA gets a lot of updates, so you can easily be left behind using the old TCA
version in your project. It’s something we experienced on our own skin. We were so much
focused on building the features and then when we decided to bump up TCA version the
changes were so groundbreaking it would take us week to migrate the whole codebase, so
we decided to stick with that old version of the library to the day.
3. Architecture - There is basically no encapsulation and you can end up having massive
reducers. On this one, I actually agree with one of creators of the TCA library Stephen Celis
who actually responded to all of the concerns Rod has in his posts, and that’s you can end
up having massive anything which is holding your app business logic, like the infamous
Massive View Controller and less famous Massive View Model.
4. Performance issue - This is actually the thing which directly led us to the decision to move to
MVVM. As the app grew, build time got super large. Also, as stated in the article, TCA uses
a lot of stack, so debugging process of some issue can be really really difficult.

To sum things up for TCA, even though we decided to move to MVVM from TCA, it is a very
powerful tool, which most certainly can be used in large scale iOS apps and big organizations. I
just believe the main two things which you need to have in order to maximize what you can get
from the TCA are a pretty damn good team of senior iOS engineers and pretty deep
understanding of all of the components in the TCA ecosystem.

www.aleksasimic.com
iOS apps architectures for large scale projects 41

CHAPTER EIGHT

Clean architecture +
Modularization,
overkill or not?
In Chapter 5: MVVM success stories, I have talked about how MVVM architecture can indeed
work pretty well for large scale iOS apps and big development times. However, I said that, in
order to get the maximum out of the MVVM architecture at scale, at least for the 60M users iOS
app I am working on, there are two additional components you can introduce to your system:

1. Clean architecture
2. Modularization

In this topic, I will, through practical examples, go trough these two components and explain
how they can be integrated with MVVM architecture so you can scale your iOS apps easily and
indefinitely.

Clean architecture. I first heard about clean architecture during faculty in one of the course I
was enrolled with. I remember my first impression being: “Oh this is so cool, but are all of these
layers? And how does this integrate into production apps?”. Fortunately, for the purpose of that
course, I didn’t have to implement clean architecture in an actual project, I just had to learn the
theory behind it, so I was pretty relieved at that point. Later, as I was finishing my master
studies, and slowly started to dive into the exciting world of iOS development, I heard about
Clean architecture here and there, but mostly in general conversations, nothing closely related
to the iOS development, so at first, I assumed it is not that relevant for iOS development. And
during my first 5 years of working as an iOS developer, during which I worked on more than 20
different iOS apps, I never once came across clean architecture. My first experience with Clean
architecture in iOS apps development, was on that large scale MVVM iOS app I mentioned
couple of times in this post. After that experience, I shifted my perspective about Clean
architecture usability in iOS apps entirely.

www.aleksasimic.com
iOS apps architectures for large scale projects 42

But for starters, let me break down all of the Clean architecture components and how all of
these components are actually present in the iOS app with Clean architecture:

1. Entity - This component of the Clean Architecture is practically as the same as Model
component from MVC and MVVM architecture. Simply put, it’s all of the business related
entities you will be using in your iOS app. Usually, in iOS apps using Clean Architecture, the
entities are named with the Entity prefix, for the example from the demo app from this e-
book:

2. Data - This component of clean architecture is the first layer of the architecture from the
bottom, and is the component which is responsible for direct communication with a remote
server or some offline database. Usually, it does that by consuming some APIClient which is
responsible for doing those operations. Also, part of this layer are entities which are coming
directly from the remote or local repository. This entities are usually named with a DTO
suffix. Later, in the clean architecture flow, they are mapped to the entities from the Entity
layer. Here are the code snippets for the data layer components in this e-book’s demo
application.

www.aleksasimic.com
iOS apps architectures for large scale projects 43

AstronomyDTO:

www.aleksasimic.com
iOS apps architectures for large scale projects 44

NasaPlanetServiceData:

3. Domain layer - this is a top-most layer in the clean architecture, and the closest one to
the rest of the app. This is the layer which view models consume in order to communicate
with the “outside world”, or as some people call it, for side effects. The domain layer holds
an reference to the data layer, uses it to make the concrete communication with the remote
server or local persistence, and optionally, adds some more mapping or functionalities to
the results obtained from the data layer. From the example in the demo app, this is how a
domain layer usually looks like:

www.aleksasimic.com
iOS apps architectures for large scale projects 45

These are the three core layers of the clean architecture, at least when we are using it for the
iOS app codebases.

How clean architecture approach then connects to the architecture your iOS app has? Simply,
the pieces of business logic, view models in MVVM, or Reducers in TCA, just connect and
consume the data from the UseCases layer, and that’s all there really is too it. That’s all you will
need to do in order to incorporate clean architecture in your existing iOS apps.

As you can see, the clean architecture takes separation of concerns on a whole another level. It
takes code separation a step further than: business logic should be in the view model, and the
rest should be in the view by adding more granularity to everything which is happening after the
code execution goes outside of the view model.

As you might already assume, embracing clean architecture in very large scale iOS apps, like the
app which I mentioned previously that I am working on alongside 20 other iOS developers,
brings many benefits to the project. The main two benefits, from my perspective and the
experience of actively using it for the past two years, are: much better separation of concerns
and code and finer granularity which together result in easier building of a large system and
making it scalable.

Modularized architecture. First of all, there are two levels of modularization:

1. Vertical modularization
2. In vertical modularization, you modularize your app vertically, by domains. Clean
architecture is a perfect example of vertical modularization. Often, when using clean
architecture, all of the layers from the clean architecture are in separate modules, SPM
packages or local Cocoapods.
3. Horizontal modularization
4. In horizontal modularization, you modularize your iOS app by features. So for example, you
would have Feature1 package, Feature 2 package etc.

From my previous experience, people usually do one of these two modularization approaches in
their iOS apps, and I have rarely seen an iOS apps which have the support for both vertical and
horizontal modularization. But if done properly, introduction of both of these modularizations
together do feel like you gave your iOS app scaling super powers.

What are my experiences with it?

When it comes to the modularization, I always read about how people from big companies are
using modularization to modularize their iOS apps, and I just couldn’t wait a moment to try it
out in some project I’m working on, too see how it works first hand.

In the beginning, I was like, there’s no need to introduce modularization and clean architecture
to the iOS apps we are just starting, those are tools that only big iOS apps actually can benefit
from. I was never so wrong in my life.

www.aleksasimic.com
iOS apps architectures for large scale projects 46

We were starting to work on an app from the scratch, and we were actually pretty heavily
discussing about whether we want clean architecture and modularization, and in the end, I
made the call and said that we shouldn’t do it in the beginning, since we still need to see
whether the app will scale or not.

Fast forward, 1.5 years into that project, I started to see that we need more control and
predictability in the project and thought to myself, how great it would be if we would now have
clean architecture and modularization in this project. I suggested that to the rest of the team
and they simply asked me, why don’t we do it now?

At first, I hesitated, because I thought it will just take too much of our time, and we still need to
develop new features and figure out the product market fit for that app. But eventually, I was
like, yeah, let’s give it a shot and try to introduce the changes in iterations. First, we added
vertical modularization by introducing clean architecture, but not for every single service we
had. We moved service by service to the Domain layer in UseCases, and moved model by model
to Entity layer. So we did it step by step, while stile delivering new features and doing
maintenance task.

Pretty soon, after couple of weeks into iterative migration, we already noticed huge
improvements all across our codebase. The code was starting to be scalable, and we felt like we
have the control over the codebase again.

At the moment, we are in final steps of finishing the vertical modularization and moving all of
the things to the clean architecture packages. Also, we are starting to introduce the horizontal
modularization also in the same project, and we already migrated one feature module entirely
into a separate SPM package with a separate, runnable, target. Now, whoever is working on that
feature, can just run that target and do the needed updates, instead of having to run the whole
project and wait for it to compile. This is a huge benefit for large scale iOS apps.

My second encounter with the clean architecture was on this big iOS app I am working on at the
moment. When I onboarded to the project, I noticed that the team was using clean architecture,
where every layer of the clean architecture was in a separate SPM package. Also, it seemed to
have integrated and working pretty well with the MVVM architecture which has been used to
drive the screens. But only when I started working hands-on with clean architecture in that
setup, I experienced hands-on how working with clean architecture feels like all of the pieces of
the puzzle coming together perfectly. The app was scaling seamlessly while keeping the
development experience and speed on the point.

Both of these experiences made me realize that the clean architecture and modularization is
something that every iOS application actually needs, not only the large scale ones. In the end,
people end up spending much more time optimizing their codebase, once their app scales,
instead of investing just a little bit more time in the beginning, to make things right.

www.aleksasimic.com
iOS apps architectures for large scale projects 47

CONCLUSION

Just The Beginning


My journey to find the “perfect” architecture for iOS
applications has indeed confirmed me that there is no
such thing as a “perfect” architecture or silver bullet
which will work for all of the iOS applications which solve
many different business problems.

However, through that journey, I have learned so much


about so many different architectural approaches and how
we can use them in large scale projects in the right way.

From the bottom of my heart, I hope that I was, through


this e-book, able to share all of my findings and insights
with you, in a clear and practical way. Also, I hope that
you will be able, based on what you read here, and the
code examples from this book’s demo app, to start
implementing some of it on your existing, and all of the
further iOS projects which come your way.

Till next time,

— Aleksa

www.aleksasimic.com
Aleksa Simic
www.aleksasimic.com
@aleksasimic

You might also like