Seda
Seda 是一个用于 SwiftUI 和 UIKit 的 Redux + 命令架构框架。
架构
Seda 的架构是 Redux 和命令的复合体。
通常,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)