Skip to content

Proposition of a Clean Architecture for iOS projects

Notifications You must be signed in to change notification settings

raphaelguye/CleanTodoList

Repository files navigation

CleanTodoList

Introduction

This is a proposition of a Clean Architecture for iOS projects.

Based on the MVVM pattern and powered by Combine.
Dependency injection made with Resolver.

This project contains two UI implementations : One with UIKit and one with SwiftUI. Both are using the same ViewModels.

SceneDelegate

For both UIKit and SwiftUI, The entry point is the SceneDelegate.
In that way, you can easily choose which App you want to start (UIKit or SwiftUI).
For a pure SwiftUI app targetting iOS14+, consider to use the @main attribute from Swift 5.3 together with the UIApplicationDelegateAdaptor from iOS 14 (example).

UIKit implementation

Implementation in code rather than with Storyboards (example). There are several advantages with this method like:

  • Each views are defined in one only file.
    With Storyboards or XIB, another ViewController file is required for the code behind and to manage the binding with the ViewModel
  • Code merging is simplified
  • Readibility is improved.
    Even a not iOS developer will be able to understand and update the views.
  • The same paradigm can be applied to any other imperative UI framework (Android, Xamarin, ReactNative, ...).
    For multi skilled teams, switching context and learning curve will be simplified

Productivity and efficiency could also be better. But for a senior developer who master UIKit, that's probably discutable.
The main cons is the learning curve of the manual implementation of the constraints.

SwiftUI implementation

With the standard ObservedObject property wrapper, the views are refreshed every time a ViewModel's property is changed/published (example in the TodoListView with its ViewModel).

The declarative syntax allow us to define easily the expected views responding to different states.
For project targetting iOS13+, it should be the default choice.

If you need, you can always create specific UIKit views and integrate it to the SwiftUI project (and vice versa). Check the Apple official lesson or the SwiftLee example.

Dependency manager

As the new standard built by Apple, consider to use Swift Packages when it's possible.
Every dependency managers have pros and cons, there are a lot of existing comparison on the web (for example here or here).

Dependency injection

Resolver and its annotation injection strategy is a good candidate for a lightweight DI strategy. It doesn't contain a lot of boilerplate code and it's easy to setup (example as described in the official documentation).
Another good choice proposed on SwiftLee is to write your own implementation without a 3rd party library.
The paper described several advantages. Consider to switch to this strategy if you want to reduce your dependencies.

TODO

  • Setup project with DI and unit tests
  • UIKit implementation - first view and navigation
  • SwiftUI implementation - first view and navigation
  • Writting doc in README
  • Create a Model
  • Create a real service connected to a back-end
  • Implement more CRUD features
  • Specify more topics (UI tests, Accessibility, Logger, ...)

About

Proposition of a Clean Architecture for iOS projects

Resources

Stars

Watchers

Forks

Languages