iOS: Repository pattern in Swift

Raul Peña Alonso
Mar 27 · 2 min read

In a previous post we had the opportunity to define the architecture of our app conceptually. The purpose of this post is to get deep into implementation of key components of this architecture we’re using.

In this post we’ll talk about how we implement:

Repository pattern

Repository pattern is a software design pattern that provides an abstraction of data, so that your application can work with a simple abstraction that has an interface. Using this pattern can help achieve loose coupling and can keep domain objects persistence ignorant.

It also makes code more testable as it allow us to inject as a dependency a mock repository that implements that defined interface.

In Tiendeo iOS app, this pattern allow us to abstract the domain layer from the data layer and also, inside data layer, the data repository from its data sources (web API, Realm, User Defaults, etc.).

Let’s see it in a simple scheme:

In domain layer, we define a RepositoryProtocol that allows us to abstract domain layer (business logic) from data layer following the dependency rule as it is recommended in clean architecture. (+info)

Let’s see it with a common example:

In the example above, the use case in domain layer just has an instance of an object that implements the FavoriteRepository protocol. This object is injected as a dependency when use case is created (+info). To use case doesn’t care about who implements this protocol, use case is abstracted from data repository.

Now, let’s see how this example continues in data layer:

In data layer, FavoritesDataRepository implements FavoriteRepository protocol defined in domain layer. It also has different data sources, in this case remoteDataSource and localDataSource, which implement the same FavoritesDataSource protocol. That abstracts FavoritesDataRepository from data sources implementation.

Each data source internally implements the code required for its source, remoteDataSource makes an Alamofire request and localDataSource uses Realm to add favorite entity to local data base.

It also interesting the way FavoritesDataRepository can manage the different data sources. In this example, using RxSwift, we execute remoteDataSource method and, in case the result is successfully, we execute localDataSource method.

But there are numerous RxSwift operators that can help you in numerous cases. We talk about RxSwift operators in other post if you interested in.

Hope you found this post interesting and useful for your projects. Any question or comment will be welcome!

Thanks and good luck!!!

Related articles

In the following posts we detail other key components from our architecture:

Tiendeo Tech

Code, thoughts and solutions — www.tiendeo.com

Raul Peña Alonso

Written by

iOS developer established in 2012

Tiendeo Tech

Code, thoughts and solutions — www.tiendeo.com