ViewStore
A ViewStore
is an object that can observe state changes and send actions. They are most commonly used in views, such as SwiftUI views, UIView or UIViewController, but they can be used anywhere it makes sense to observe state or send actions.
- iOS
- deprecated
- macOS
- deprecated
- tvOS
- deprecated
- watchOS
- deprecated
@dynamicMemberLookup @preconcurrency @MainActor final class ViewStore<ViewState, ViewAction>
In SwiftUI applications, a ViewStore
is accessed most commonly using the WithViewStore
view. It can be initialized with a store and a closure that is handed a view store and returns a view:
var body: some View {
WithViewStore(self.store, observe: { $0 }) { viewStore in
VStack {
Text("Current count: \(viewStore.count)")
Button("Increment") { viewStore.send(.incrementButtonTapped) }
}
}
}
View stores can also be observed directly by views, scenes, commands, and other contexts that support the @ObservedObject
property wrapper:
@ObservedObject var viewStore: ViewStore<State, Action>
In UIKit applications a ViewStore
can be created from a Store
and then subscribed to for state updates:
let store: Store<State, Action>
let viewStore: ViewStore<State, Action>
private var cancellables: Set<AnyCancellable> = []
init(store: Store<State, Action>) {
self.store = store
self.viewStore = ViewStore(store, observe: { $0 })
}
func viewDidLoad() {
super.viewDidLoad()
self.viewStore.publisher.count
.sink { [weak self] in self?.countLabel.text = $0 }
.store(in: &self.cancellables)
}
@objc func incrementButtonTapped() {
self.viewStore.send(.incrementButtonTapped)
}
Creating a view store
init<State, Action>(Store<State, Action>, observe: @escaping (_ state: State) -> ViewState, send: @escaping (_ viewAction: ViewAction) -> Action, removeDuplicates: @escaping (_ lhs: ViewState, _ rhs: ViewState) -> Bool
) Initializes a view store from a store which observes changes to state.
init<State>(Store<State, ViewAction>, observe: @escaping (_ state: State) -> ViewState, removeDuplicates: @escaping (_ lhs: ViewState, _ rhs: ViewState) -> Bool
) Initializes a view store from a store which observes changes to state.
init<State, Action>(Store<State, Action>, observe: @escaping (_ state: State) -> ViewState, send: @escaping (_ viewAction: ViewAction) -> Action
) Initializes a view store from a store which observes changes to state.
init<State>(Store<State, ViewAction>, observe: @escaping (_ state: State) -> ViewState
) Initializes a view store from a store which observes changes to state.
typealias ViewStoreOf<R>
A convenience type alias for referring to a view store of a given reducer’s domain.
Accessing state
var state: ViewState
The current state.
subscript<Value>(dynamicMember: KeyPath<ViewState, Value>
) -> Value Returns the resulting value of a given key path.
Sending actions
func send(ViewAction
) -> StoreTask Sends an action to the store.
func send(ViewAction, while: @escaping (_ state: ViewState) -> Bool
) async Sends an action into the store and then suspends while a piece of state is
true
.func yield(while: @escaping (_ state: ViewState) -> Bool
) async Suspends the current task while a predicate on state is
true
.
SwiftUI integration
func send(ViewAction, animation: Animation?
) -> StoreTask Sends an action to the store with a given animation.
func send(ViewAction, animation: Animation?, while: @escaping (_ state: ViewState) -> Bool
) async Sends an action into the store and then suspends while a piece of state is
true
.func send(ViewAction, transaction: Transaction
) -> StoreTask Sends an action to the store with a given transaction.
Working with SwiftUI bindings
Learn how to connect features written in the Composable Architecture to SwiftUI bindings.
Read Morenonisolated let objectWillChange: ObservableObjectPublisher
init<State, Action>(Store<State, Action>, observe: @escaping (_ state: BindingViewStore<State>) -> ViewState, send: @escaping (_ viewAction: ViewAction) -> Action, removeDuplicates: @escaping (_ lhs: ViewState, _ rhs: ViewState) -> Bool
) Initializes a structure that transforms a
Store
into an observableViewStore
in order to compute bindings from state.init<State>(Store<State, ViewAction>, observe: @escaping (_ state: BindingViewStore<State>) -> ViewState, removeDuplicates: @escaping (_ lhs: ViewState, _ rhs: ViewState) -> Bool
) Initializes a structure that transforms a
Store
into an observableViewStore
in order to compute bindings from state.init<State, Action>(Store<State, Action>, observe: @escaping (_ state: BindingViewStore<State>) -> ViewState, send: @escaping (_ viewAction: ViewAction) -> Action
) Initializes a structure that transforms a
Store
into an observableViewStore
in order to compute bindings from state.init<State>(Store<State, ViewAction>, observe: @escaping (_ state: BindingViewStore<State>) -> ViewState
) Initializes a structure that transforms a
Store
into an observableViewStore
in order to compute bindings from state.subscript<Value>(dynamicMember: WritableKeyPath<ViewState, BindingState<Value>>
) -> Binding<Value>