Seda 0.1.6

Seda 0.1.6

Ryoichi Izumita 维护。



Seda 0.1.6

Seda

Build Status

Seda 是一个用于 SwiftUI 和 UIKit 的 Redux + 命令架构框架。

架构

Seda 的架构是 Redux 和命令的复合体。

Architecture

通常,Redux 的 reducer 仅返回状态。但 Seda 的 reducer 会返回状态和 'Command',如下所示。

func reducer() -> Reducer<AppState> {
    return { action, state in
        var state = state
        var command = Command.none
        ...
        switch action {
        case Foo.asyncAction:
            command = Command.ofAsyncAction { fullfill in
                asyncFunc { value in fulfill(Foo.updateValue(value)) }
            }
        case Foo.updateValue(let value):
            state.value = value
        ...
        }
        ...
        return (state, command)
    }
}

Command 管理异步和副作用任务。命令包裹的任务不会泄漏到应该是纯函数的 reducer。正因为如此,我们才能在 reducer 中安全地编写异步和副作用任务。

安装

Swift 包管理器

在 Xcode 中,选择 '文件' 菜单 -> 'Swift 包' -> '添加包依赖...'。

CocoaPods

在 Podfile 中,

pod 'Seda', '~> 0.1'

并执行 pod install

如何使用

本质上,Seda 几乎与 Redux 相似。

定义状态

定义 Redux 的状态。状态必须遵循 StateType 协议。

struct State: StateType {
    var count: Int = 0
}

定义动作

定义 Redux 的动作。动作必须遵循 ActionType 协议。

enum CountAction: ActionType {
    case step(Step)
    case stepDelayed(Step)
}

实现减速器

Seda 的减速器与 Redux 的减速器略有不同。

减速器类型必须是 Reducer

减速器会使用动作和状态来调用。然后减速器返回状态和命令。

typealias CounterReducer = Reducer<State>

func counterReducer() -> CounterReducer {
    return { action, state in
        var state = state
        var command = Command.none

        switch action {
        case CountAction.step(let step):
            state.count += step.count
            state.history.append(step)

        case CountAction.stepDelayed(let step):
            command = .ofAsyncAction { fulfill in
                DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(2)) {
                    fulfill(CountAction.step(step))
                }
            }

        default: ()
        }

        return (state, command)
    }
}

定义视图

定义 SwiftUI 视图。视图必须遵循 StatefulView 协议。

struct CounterView: StatefulView {
    @EnvironmentObject var store: Store<State>

    var body: some View {
        ...
    }
}

创建存储并通过存储传递给视图

let store = Store<State>(reducer: counterReducer(), state: State())
let counterView = CounterView().environmentObject(store)