Example of Clean Architecture of iOS app using RxSwift
Alternatives To Cleanarchitecturerxswift
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
3 months ago43mitSwift
Bark is an iOS App which allows you to push custom notifications to your iPhone
10 months ago28mitSwift
Example of Clean Architecture of iOS app using RxSwift
a month ago22mitSwift
GitHub iOS client in RxSwift and MVVM-C clean architecture
4a month ago22February 03, 202015mitSwift
🎌 Powerful navigation library for iOS based on the coordinator pattern
5 years ago2mitC
🥇Swift基础知识大全,🚀Swift学习从简单到复杂,不断地完善与更新, 欢迎Star❤️,欢迎Fork, iOS开发者交流:①群:446310206 ②群:426087546
3 years ago18apache-2.0Swift
🌁 An Unsplash app for iOS
4 years ago2mitSwift
Examples and resources for RxSwift.
Ios Architecture731
4 years ago3mitSwift
A collection of iOS architectures - MVC, MVVM, MVVM+RxSwift, VIPER, RIBs and many others
2 months agomitSwift
Sample iOS app demonstrating Coordinators, Dependency Injection, MVVM, Binding
Swift Verge529
112 days ago87August 27, 202210mitSwift
🟣 A robust Swift state-management framework designed for complex applications, featuring an integrated ORM for efficient data handling.
Alternatives To Cleanarchitecturerxswift
Select To Compare

Alternative Project Comparisons

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


Dependencies in this project are provided via Cocoapods. Please install all dependecies with

pod install

You can run this script ( in 'scripts' folder that help you install all dependecies

High level overview


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


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 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 UIViews and UIViewControllers. 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.


Entities are implemented as Swift value types

public struct Post {
    public let uid: String
    public let createDate: Date
    public let updateDate: Date
    public let title: String
    public let content: String

UseCases are protocols which do one specific thing:

public protocol PostsUseCase {
    func posts() -> Observable<[Post]>
    func save(post: Post) -> Observable<Void>

UseCaseProvider is a service locator. In the current example, it helps to hide the concrete implementation of use cases.


In some cases, we can't use Swift structs for our domain objects because of DB framework requirements (e.g. CoreData, Realm).

final class CDPost: NSManagedObject {
    @NSManaged public var uid: String?
    @NSManaged public var title: String?
    @NSManaged public var content: String?
    @NSManaged public var createDate: NSDate?
    @NSManaged public var updateDate: NSDate?

final class RMPost: Object {
    dynamic var uid: String = ""
    dynamic var createDate: NSDate = NSDate()
    dynamic var updateDate: NSDate = NSDate()
    dynamic var title: String = ""
    dynamic var content: String = ""

The Platform also contains concrete implementations of your use cases, repositories or any services that are defined in the Domain.

final class PostsUseCase: Domain.PostsUseCase {
    private let repository: AbstractRepository<Post>

    init(repository: AbstractRepository<Post>) {
        self.repository = repository

    func posts() -> Observable<[Post]> {
        return repository.query(sortDescriptors: [Post.CoreDataType.uid.descending()])
    func save(post: Post) -> Observable<Void> {
        return post)

final class Repository<T: CoreDataRepresentable>: AbstractRepository<T> where T == T.CoreDataType.DomainType {
    private let context: NSManagedObjectContext
    private let scheduler: ContextScheduler

    init(context: NSManagedObjectContext) {
        self.context = context
        self.scheduler = ContextScheduler(context: context)

    override func query(with predicate: NSPredicate? = nil,
                        sortDescriptors: [NSSortDescriptor]? = nil) -> Observable<[T]> {
        let request = T.CoreDataType.fetchRequest()
        request.predicate = predicate
        request.sortDescriptors = sortDescriptors
        return context.rx.entities(fetchRequest: request)

    override func save(entity: T) -> Observable<Void> {
        return entity.sync(in: context)

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.

public final class UseCaseProvider: Domain.UseCaseProvider {
    private let coreDataStack = CoreDataStack()
    private let postRepository: Repository<Post>

    public init() {
        postRepository = Repository<Post>(context: coreDataStack.context)

    public func makePostsUseCase() -> Domain.PostsUseCase {
        return PostsUseCase(repository: postRepository)


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

protocol ViewModelType {
    associatedtype Input
    associatedtype Output
    func transform(input: Input) -> Output
final class PostsViewModel: ViewModelType {
    struct Input {
        let trigger: Driver<Void>
        let createPostTrigger: Driver<Void>
        let selection: Driver<IndexPath>
    struct Output {
        let fetching: Driver<Bool>
        let posts: Driver<[Post]>
        let createPost: Driver<Void>
        let selectedPost: Driver<Post>
        let error: Driver<Error>
    private let useCase: AllPostsUseCase
    private let navigator: PostsNavigator
    init(useCase: AllPostsUseCase, navigator: PostsNavigator) {
        self.useCase = useCase
        self.navigator = navigator
    func transform(input: Input) -> Output {

A ViewModel can be injected into a ViewController via property injection or initializer. In the current example, this is done by Navigator.

protocol PostsNavigator {
    func toCreatePost()
    func toPost(_ post: Post)
    func toPosts()

class DefaultPostsNavigator: PostsNavigator {
    private let storyBoard: UIStoryboard
    private let navigationController: UINavigationController
    private let services: ServiceLocator
    init(services: ServiceLocator,
         navigationController: UINavigationController,
         storyBoard: UIStoryboard) { = services
        self.navigationController = navigationController
        self.storyBoard = storyBoard
    func toPosts() {
        let vc = storyBoard.instantiateViewController(ofType: PostsViewController.self)
        vc.viewModel = PostsViewModel(useCase: services.getAllPostsUseCase(),
                                      navigator: self)
        navigationController.pushViewController(vc, animated: true)

class PostsViewController: UIViewController {
    private let disposeBag = DisposeBag()
    var viewModel: PostsViewModel!


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


The corner stone of Clean Architecture is modularization, as you can hide implementation detail under internal access layer. Further read of this topic here


  • add tests
  • add MVP example
  • Redux example??


Any questions?

Popular Rxswift Projects
Popular Mvvm Projects
Popular Control Flow Categories
Related Searches

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Reactive Programming