The Gist

A more advanced Swift example of the original gist

import ReduxKit

/**
 This is an extremely simple and flexible action. The only requirement for actions is that they
 conform to the Action protocol.

 The Action protocol can be inherited from for app specific Action requirements. For a good example
 of this, see FluxStandardAction and the implementing types in the source.

 Action can be implemented as an enum, struct or class.
 */
struct IncrementAction: Action {
    let payload: Int
    init(payload: Int = 1) {
        self.payload = payload
    }
}

struct DecrementAction: Action {
    let payload: Int
    init(payload: Int = 1) {
        self.payload = payload
    }
}

/**
 This is a simple reducer. It is a pure function that follows the syntax (State, Action) -> State.
 It describes how an action transforms the previous state into the next state.

 Instead of using the Action.type property - as is done in the regular Redux framework we use the
 power of Swifts static typing to deduce the action.
 */
func counterReducer(previousState: Int?, action: Action) -> Int {
    // Declare the reducers default value
    let defaultValue = 0
    var state = previousState ?? defaultValue

    switch action {
        case let action as IncrementAction:
            return state + action.payload
        case let action as DecrementAction:
            return state - action.payload
        default:
            return state
    }
}

/**
 The applications state. This should contain the state of the whole application.
 When building larger applications, you can optionally assign complex structs to properties on the
 AppState and handle them in the part of the application that uses them.
 */
struct AppState {
    var count: Int!
}

/**
 Create the applications reducer. While we could create a combineReducer function we've currently
 chosen to allow reducers to be statically typed and accept static states - instead of Any - which
 currently forces us to define the application reducer as such. This could possibly be simplified
 with reflection.
 */
let applicationReducer = {(state: AppState? = nil, action: Action) -> AppState in

    return AppState(
        count: counterReducer(state?.count, action: action),
    )
}

// Create application store. The second parameter is an optional default state.
let store = createStore(applicationReducer, nil)

let disposable = store.subscribe { state in
    print(state)
}


store.dispatch(IncrementAction())
// {counter: 1}

store.dispatch(IncrementAction())
// {counter: 2}

store.dispatch(DecrementAction())
// {counter: 1}

// Dispose of the subscriber after use.
disposable.dispose()