Store - mbrandonw/swift-composable-architecture GitHub Wiki

Store

A store represents the runtime that powers the application. It is the object that you will pass around to views that need to interact with the application.

public final class Store<State, Action>

You will typically construct a single one of these at the root of your application, and then use the scope method to derive more focused stores that can be passed to subviews.

Initializers

init(initialState:reducer:environment:)

Initializes a store from an initial state, a reducer, and an environment.

public convenience init<Environment>(initialState: State, reducer: Reducer<State, Action, Environment>, environment: Environment)

Parameters

  • initialState: - initialState: The state to start the application in.
  • reducer: - reducer: The reducer that powers the business logic of the application.
  • environment: - environment: The environment of dependencies for the application.

init(initialState:reducer:)

private init(initialState: State, reducer: @escaping (inout State, Action) -> Effect<Action, Never>)

Properties

state

var state: CurrentValueSubject<State, Never>

effectCancellables

var effectCancellables: [UUID: AnyCancellable]

isSending

var isSending

parentCancellable

var parentCancellable: AnyCancellable?

reducer

let reducer: (inout State, Action) -> Effect<Action, Never>

synchronousActionsToSend

var synchronousActionsToSend: [Action]

stateless

Returns a "stateless" store by erasing state to Void.

var stateless: Store<Void, Action>

actionless

Returns an "actionless" store by erasing action to Never.

var actionless: Store<State, Never>

Methods

scope(state:action:)

Scopes the store to one that exposes local state and actions.

public func scope<LocalState, LocalAction>(state toLocalState: @escaping (State) -> LocalState, action fromLocalAction: @escaping (LocalAction) -> Action) -> Store<LocalState, LocalAction>

This can be useful for deriving new stores to hand to child views in an application. For example:

// Application state made from local states.
struct AppState { var login: LoginState, ... }
struct AppAction { case login(LoginAction), ... }

// A store that runs the entire application.
let store = Store(initialState: AppState(), reducer: appReducer, environment: ())

// Construct a login view by scoping the store to one that works with only login domain.
let loginView = LoginView(
  store: store.scope(
    state: { $0.login },
    action: { AppAction.login($0) }
  )
)

Parameters

  • toLocalState: - toLocalState: A function that transforms State into LocalState.
  • fromLocalAction: - fromLocalAction: A function that transforms LocalAction into Action.

Returns

A new store with its domain (state and action) transformed.

scope(state:)

Scopes the store to one that exposes local state.

public func scope<LocalState>(state toLocalState: @escaping (State) -> LocalState) -> Store<LocalState, Action>

Parameters

  • toLocalState: - toLocalState: A function that transforms State into LocalState.

Returns

A new store with its domain (state and action) transformed.

scope(state:action:)

Scopes the store to a publisher of stores of more local state and local actions.

public func scope<P: Publisher, LocalState, LocalAction>(state toLocalState: @escaping (AnyPublisher<State, Never>) -> P, action fromLocalAction: @escaping (LocalAction) -> Action) -> AnyPublisher<Store<LocalState, LocalAction>, Never> where P.Output == LocalState, P.Failure == Never

Parameters

  • toLocalState: - toLocalState: A function that transforms a publisher of State into a publisher of LocalState.
  • fromLocalAction: - fromLocalAction: A function that transforms LocalAction into Action.

Returns

A publisher of stores with its domain (state and action) transformed.

scope(state:)

Scopes the store to a publisher of stores of more local state and local actions.

public func scope<P: Publisher, LocalState>(state toLocalState: @escaping (AnyPublisher<State, Never>) -> P) -> AnyPublisher<Store<LocalState, Action>, Never> where P.Output == LocalState, P.Failure == Never

Parameters

  • toLocalState: - toLocalState: A function that transforms a publisher of State into a publisher of LocalState.

Returns

A publisher of stores with its domain (state and action) transformed.

send(_:)

func send(_ action: Action)

ifLet(then:else:)

Subscribes to updates when a store containing optional state goes from nil to non-nil or non-nil to nil.

public func ifLet<Wrapped>(then unwrap: @escaping (Store<Wrapped, Action>) -> Void, else: @escaping () -> Void) -> Cancellable where State == Wrapped?

This is useful for handling navigation in UIKit. The state for a screen that you want to navigate to can be held as an optional value in the parent, and when that value switches from nil to non-nil you want to trigger a navigation and hand the detail view a Store whose domain has been scoped to just that feature:

class MasterViewController: UIViewController {
  let store: Store<MasterState, MasterAction>
  var cancellables: Set<AnyCancellable> = []
  ...
  func viewDidLoad() {
    ...
    self.store
      .scope(state: \.optionalDetail, action: MasterAction.detail)
      .ifLet(
        then: { [weak self] detailStore in
          self?.navigationController?.pushViewController(
            DetailViewController(store: detailStore),
            animated: true
          )
        },
        else: { [weak self] in
          guard let self = self else { return }
          self.navigationController?.popToViewController(self, animated: true)
        }
      )
      .store(in: &self.cancellables)
  }
}

Parameters

  • unwrap: - unwrap: A function that is called with a store of non-optional state whenever the store's optional state goes from nil to non-nil.
  • else: - else: A function that is called whenever the store's optional state goes from non-nil to nil.

Returns

A cancellable associated with the underlying subscription.

ifLet(then:)

An overload of ifLet(then:else:) for the times that you do not want to handle the else case.

public func ifLet<Wrapped>(then unwrap: @escaping (Store<Wrapped, Action>) -> Void) -> Cancellable where State == Wrapped?

Parameters

  • unwrap: - unwrap: A function that is called with a store of non-optional state whenever the store's optional state goes from nil to non-nil.

Returns

A cancellable associated with the underlying subscription.

⚠️ **GitHub.com Fallback** ⚠️