ViewModel
@MainActor
@dynamicMemberLookup
public final class ViewModel<State, Event> : ObservableObject where State : Equatable
A view model wraps a store and observes state changes that can be used within a view.
extension RootScreen {
struct ContentView: View {
let store: Store
@StateObject var viewModel: ViewModel<AppState, AppEvent>
// MARK: Body
var body: some View {
VStack(alignment: .center) {
Text(verbatim: .init(self.viewModel.count))
.font(.largeTitle)
HStack {
Button("Decrement") {
self.viewModel.send(.decrement)
}
.buttonStyle(.bordered)
Button("Increment") {
self.viewModel.send(.increment)
}
.buttonStyle(.bordered)
Button("Delayed increment") {
self.viewModel.send(.incrementWithDelay)
}
.buttonStyle(.bordered)
}
}
}
}
}
-
The state of the store.
Declaration
Swift
@Published public var state: State { get set }
-
Create a new view model instance.
Declaration
Swift
public init<Environment>(_ store: Store<State, Event, Environment>)
Parameters
store
The store.
-
Send an event to the store.
Declaration
Swift
public func send(_ event: Event)
Parameters
event
The even to send.
-
Returns the resulting state value of a given key path.
Declaration
Swift
public subscript<T>(dynamicMember keyPath: KeyPath<State, T>) -> T { get }
-
Creates a
Binding
that prevents direct write access to the state and instead sends an event onset
.This makes working with SwiftUI components easier.
For example:
TextField( "Email", text: viewStore.binding( get: \.email, send: { .setEmail($0) } ) )
Declaration
Swift
public func binding<ScopedState>( value: @escaping (State) -> ScopedState, event: @escaping (ScopedState) -> Event ) -> Binding<ScopedState> where ScopedState: Equatable
Parameters
value
A function to extract the value from the state.
event
A function to build the event that is sent to the store.
Return Value
A binding.
-
Creates a
Binding
that prevents direct write access to the state and instead sends an event onset
.This makes working with SwiftUI components easier.
For example:
SomeView() .alert( "Error", isPresented: self.store.binding( value: { $0.loginStatus.isFailed }, event: .resetLoginState ), actions: { }, message: { Text(self.store.loginStatus.failedMessage) } )
Declaration
Swift
public func binding<ScopedState>( value: @escaping (State) -> ScopedState, event: Event ) -> Binding<ScopedState> where ScopedState: Equatable
Parameters
value
A function to extract the value from the state.
event
An event that is sent to the store.
Return Value
A binding.
-
Creates a readonly
Binding
.This makes working with SwiftUI components easier.
For example:
.fullScreenCover( isPresented: self.viewModel.binding( value: { !$0.isLoggedIn } ), onDismiss: nil, content: { Text("Logged out") } )
Declaration
Swift
public func binding<ScopedState>( value: @escaping (State) -> ScopedState ) -> Binding<ScopedState>
Parameters
value
A function to extract the value from the state.
Return Value
A readonly binding.