Clean Architecture and MVVM on iOS (Swift) part 2

Tram Ho

In part 1 we learned about Clean Architecture. In this part 2, we will continue with the MVVM model in the Clean Architecture series and MVVM on iOS (Swift).

MVVM

Model-View-ViewModel pattern (MVVM) clearly separates UI and domain. When using them (MVVM) with Clean Architecture can clearly separate between UI and Presentation layers.

Implementations of different Views can use the same ViewModel . For example, you can implement CarsAroundListView and CarsAroundMapView and use CarsAroundViewModel for both. You can also implement another UIkit View and View with SwiftUI . It’s important to remember not to import UIkit, WatchKit, or SwiftUI inside your ViewModel , so you can reuse it in other platforms if needed.

° ° °

image.png

For example, data binding between View and ViewModel can be done with closures , Delegate or Observerble (e.g. RxSwift). Combine and SwiftUI can also be used but only if the iOS system is >= 13. The View has a direct relationship with the ViewModel and notifies it whenever an event inside the View occurs. From the ViewModel , there is no direct reference to the View (only Data Binding).

In this example, we’ll use a simple combination of Closure and didSet to avoid third-party dependencies:

Note: Here is a very simple version of Observable, to see the whole implementation with multiple observerble and observer removal : Observerble .

An example of Data Binding of ViewController:

Note : Accessing the viewModel from the observing closure is not allowed. It is the cause of the retain cycle (memory leak). You can access the viewModel just by self: self?.viewModel.

An example data binding on TableViewCell (Reusable Cell):

Note : We must unbind if the View is reusable (e.g. UITableViewCell)

MVVM Templates can be viewed here

MVVMs Communication

Delegation

The ViewModel of one MVVM (screen) communicates with another ViewModel of another MVVM (screen) using the delegation pattern:

image.png

For example, we have ItemsListViewModel and ItemEditViewModel . Then create a protocol ItemEditViewModelDelegate with the ItemEditViewModelDidEditItem(item) method. And for the viewmodel to conform to this protocol: extension ListItemsViewModel: ItemEditViewModelDelegate

Note : We can also name the Delegates in this case as a Responders: ItemEditViewModelResponder

Closures

Another way to communicate is to use closures specified or included by the FlowCoordinator . In the example project we can see how the MoviesListViewModel uses the showMovieQueriesSuggestions action closure to show MoviesQueriesSuggestionsView . It also passes the parameter (_ didSelect: MovieQuery) -> Void so they can also be called from that View. how this communication is connected inside MoviesSearchFlowCoordinator , see example below:

Split layers into frameworks (Modules)

Now, each layer (Domain, Presentation, UI, Data, Infrastructure Network) of the example app can be easily split into separate frameworks.

You can then incorporate those frameworks into your project using CocoaPods. You can see an example project here :

Note: You need to delete ExampleMVVM.xcworkspace and run pod install to create a new one, because it’s a licensing issue.

° ° °

image.png

° ° °

Dependency Injection Container

Dependency injection is a technique whereby one object provides the dependencies of another object. The DIContainer in your application is the central unit of all injections.

Using dependencies factory protocols

One of the options for declaring a dependency protocol is delegates, the initialization of the dependency for the DIContainer . To do this, we need to define the MoviesSearchFlowCoordinatorDependencies protocol and have the MoviesSceneDIContainer confirm the protocol itself, and then, inside the MoviesSearchFlowCoordinator as a param to initialize and present the MoviesListViewController . Here are the steps:

Using closures

Another option is closures . To do this we need to declare the closure inside the class to be injected and then we inject this closure. For example:

Source code

Resources

Advanced iOS App Architecture

The Clean Architecture

The Clean Code

Conclude

Architectural patterns used mostly in mobile are Clean Architecture(Layered), MVVM, and Redux.

MVVM and Clean Architecture can of course be used separately, but MVVM only separates the inside of the Presentation Layer, while Clean Architecture separates your code into modular layers that can make your project easily testable, reproducible. use.

It is important not to skip creating a Use Case, even though the Use Case does nothing but call the Repository. This way, your architecture will be easy to understand when a new developer sees your use cases.

While this will be helpful as a starting point, there is no product, method or trick that can guarantee the best results. Depending on the needs of the project, you can choose a suitable architecture.

Clean Architecture works really well with (Test Driven Development) TDD. This architecture makes your project testable and easily replaceable layers (UI and Data).

END

Original article link: https://tech.olx.com/clean-architecture-and-mvvm-on-ios-c9d167d9f5b3

Share the news now

Source : Viblo