Clean architecture with RxSwift
Contributions are welcome and highly appreciated!!
You can do this by:
- opening an issue to discuss the current solution, ask a question, propose your solution etc. (also English is not my native language so if you think that something can be corrected please open a PR ?)
- opening a PR if you want to fix bugs or improve something
Installation
Dependencies in this project are provided via Cocoapods. Please install all dependecies with
pod install
High level overview
Domain
The Domain
is basically what is your App about and what it can do (Entities, UseCase etc.) It does not depend on UIKit or any persistence framework, and it doesn't have implementations apart from entities
Platform
The Platform
is a concrete implementation of the Domain
in a specific platform like iOS. It does hide all implementation details. For example Database implementation whether it is CoreData, Realm, SQLite etc.
Application
Application
is responsible for delivering information to the user and handling user input. It can be implemented with any delivery pattern e.g (MVVM, MVC, MVP). This is the place for your UIView
s and UIViewController
s. As you will see from the example app, ViewControllers
are completely independent of the Platform
. The only responsibility of a view controller is to "bind" the UI to the Domain to make things happen. In fact, in the current example we are using the same view controller for Realm and CoreData.
Detail overview
To enforce modularity, Domain
, Platform
and Application
are separate targets in the App, which allows us to take advantage of the internal
access layer in Swift to prevent exposing of types that we don't want to expose.
Domain
Entities are implemented as Swift value types
UseCases are protocols which do one specific thing:
UseCaseProvider
is a service locator. In the current example, it helps to hide the concrete implementation of use cases.
Platform
In some cases, we can't use Swift structs for our domain objects because of DB framework requirements (e.g. CoreData, Realm).
The Platform
also contains concrete implementations of your use cases, repositories or any services that are defined in the Domain
.
As you can see, concrete implementations are internal, because we don't want to expose our dependecies. The only thing that is exposed in the current example from the Platform
is a concrete implementation of the UseCaseProvider
.
Application
In the current example, Application
is implemented with the MVVM pattern and heavy use of RxSwift, which makes binding very easy.
Where the ViewModel
performs pure transformation of a user Input
to the Output
A ViewModel
can be injected into a ViewController
via property injection or initializer. In the current example, this is done by Navigator
.
Example
The example app is Post/TODOs app which uses Realm
, CoreData
and Network
at the same time as a proof of concept that the Application
level is not dependant on the Platform level implementation details.
CoreData | Realm | Network |
---|---|---|
![]() |
![]() |
![]() |
Modularization
The corner stone of Clean Architecture is modularization, as you can hide implementation detail under internal
access layer. Further read of this topic here
TODO:
Links
Any questions?
- ping me on Twitter