ObservableViewModel
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
open class ObservableViewModel<ViewAction, ViewState> : StoreType, ObservableObject
A Store Projection made to be used in SwiftUI
All you need is to create an instance of this class by projecting the main store and providing maps for state and actions. For the consumers, it will act as a real Store, but in fact it’s only a proxy to the main store but working in types more close to what a View should know, instead of working on global domain.
┌────────┐
│ Button │────────┐
└────────┘ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┏━━━━━━━━━━━━━━━━━━━━━━━┓
┌──────────────────┐ │ dispatch ┃ ┃░
│ Toggle │───┼────────────────────▶│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─▶ │────────────▶┃ ┃░
└──────────────────┘ │ view event f: (Event) → Action app action ┃ ┃░
┌──────────┐ │ │ │ ┃ ┃░
│ onAppear │───────┘ ┃ ┃░
└──────────┘ │ ObservableViewModel │ ┃ ┃░
┃ ┃░
│ a projection of │ projection ┃ Store ┃░
the actual store ┃ ┃░
│ │ ┃ ┃░
┌────────────────────────┐ ┃ ┃░
│ │ │ │ ┌┃─ ─ ─ ─ ─ ┐ ┃░
│ @ObservedObject │◀ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ◀─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ◀─ ─ ─ ─ ─ ─ State ┃░
│ │ view state │ f: (State) → View │ app state │ Publisher │ ┃░
└────────────────────────┘ State ┳ ─ ─ ─ ─ ─ ┃░
│ │ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ ┗━━━━━━━━━━━━━━━━━━━━━━━┛░
▼ ▼ ▼ ░░░░░░░░░░░░░░░░░░░░░░░░░
┌────────┐ ┌────────┐ ┌────────┐
│ Text │ │ List │ │ForEach │
└────────┘ └────────┘ └────────┘
-
Undocumented
Declaration
Swift
@Published public var state: ViewState { get set }
-
Declaration
Swift
public let statePublisher: UnfailablePublisherType<ViewState>
-
Undocumented
Declaration
Swift
public init<S>(initialState: ViewState, store: S, emitsValue: ShouldEmitValue<ViewState>) where S: StoreType, S.ActionType == ViewAction, S.StateType == ViewState
-
Declaration
Swift
open func dispatch(_ dispatchedAction: DispatchedAction<ViewAction>)
-
Mock for using in tests or SwiftUI previews, available in DEBUG mode only You can use if as a micro-redux for tests and SwiftUI previews, for example:
let mock = ObservableViewModel<(user: String, pass: String, buttonEnabled: Bool), ViewAction>.mock( state: (user: "ozzy", pass: "", buttonEnabled: false), action: { action, state in switch action { case let .userChanged(newUser): state.user = newUser state.buttonEnabled = !state.user.isEmpty && !state.pass.isEmpty case let .passwordChanged(newPass): state.pass = newPass state.buttonEnabled = !state.user.isEmpty && !state.pass.isEmpty case .buttonTapped: print("Button tapped") } } )
Declaration
Swift
public static func mock(state: StateType, action: (@escaping (ActionType, ActionSource, inout StateType) -> Void) = { _, _, _ in }) -> ObservableViewModel<ActionType, StateType>
Parameters
state
Initial state mock
action
a simple reducer function, of type
(ActionType, inout StateType) -> Void
, useful if you want to use in SwiftUI live previews and quickly change an UI property when a button is tapped, for example. It’s like a micro-redux for tests and SwiftUI previews. Defaults to do nothing.Return Value
a very simple ObservableViewModel mock, that you can inject in your SwiftUI View for tests or live preview.
-
Undocumented
Declaration
Swift
public convenience init<S: StoreType>(initialState: ViewState, store: S) where S.ActionType == ViewAction, S.StateType == ViewState