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.

Available where ViewState: Equatable

  • Undocumented

    Declaration

    Swift

    public convenience init<S: StoreType>(initialState: ViewState, store: S)
    where S.ActionType == ViewAction, S.StateType == ViewState