Skip to content

Chapter 2. Drive.

Dmitriy Shulzhenko edited this page Oct 11, 2020 · 25 revisions

State.

Let's begin with the State. It can be a shared app component state or a simple view state.

I will not explain why state management is important to write better organised code. Here I will focus on how I usually use it.

It is not possible to achieve perfect characteristics all of the times due to legacy Apple patters, but I hope that things will change over time with the help of Combine.

Rules for "perfect" State. :

  • It is Observable. Every other component knows about State changes and can react immediately - perform actions or side effects
  • It is immutable for the outside world. This means that other parts can only read it, observe and react, not to change directly.

Here is simple possible definition of State

import RxSwift
import RxCocoa

protocol MovieDetailState {
    var data: Driver<MovieDetailData> { get }
    var close: Signal<Void> { get }
}

Where data is used to display some cells and close as navigation trigger.

Action

State must be changed only through Actions. It is simply just has to pass information and trigger state change.

Primitive action may be like this one:

protocol MovieDetailAction {
    func close()
}

Driver.

Driver holds State and mutates it in response to Action. The same as ViewModel in MVVM.

typealias MovieDetailDriving = MovieDetailState & MovieDetailAction
final class MovieDetailDriver: MovieDetailDriving {
    private let closeRelay = PublishRelay<Void>()
    
    private let id: Int
    private let api: TMDBApiProvider
    
    var data: Driver<MovieDetailData> {
        api.fetchMovieDetails(forMovieId: id)
            .unwrap()
            .compactMap(MovieDetailData.init)
            .asDriver()
    }
    
    var didClose: Driver<Void> { closeRelay.asDriver() }
    
    init(id: Int, api: TMDBApiProvider) {
        self.id = id
        self.api = api
    }
    
    func close() {
        closeRelay.accept(())
    }
}

Next I will show how to bind our ViewController with the Driver.

Clone this wiki locally