SwiftFlux 0.6.2

SwiftFlux 0.6.2

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2016年9月
SPM支持 SPM

Kenichi Yonekawa 维护。



SwiftFlux 0.6.2

  • Kenichi Yonekawa

SwiftFlux

SwiftFlux 是 Facebook 的 Flux 架构在 Swift 中的实现。
它通过 Swift 语言提供了“单向数据流”的概念和通过类型安全的模块。

  • 动作的有效载荷的类型是由动作的类型推导的。
  • 动作的结果通过 Result 表示,也称为 Either。
  • 订阅存储来了解状态变化。

要求

  • Swift 2.2 或更高版本
  • iOS 8.0 或更高版本
  • macOS 10.9 或更高版本
  • watchOS 2.0 或更高版本

用法

步骤 1:定义动作

  • 将表示结果对象的类型分配给 Payload 的 `typealias`。
  • 定义 `invoke` 向存储派发动作。
  • 您可以在这里调用 API 请求(您可以使用异步请求)。
struct TodoAction {
    struct Create : Action {
        typealias Payload = Todo
        func invoke(dispatcher: Dispatcher) {
            let todo = Todo(title: "New ToDo")
            dispatcher.dispatch(self, result: Result(value: todo))
        }
    }
}

步骤 2:定义存储并注册动作以分派

  • 将任何订阅动作回调注册到分派器。
  • 在回调中由 Either 解包动作结果值。
  • 通过 `emitChange` 通过向订阅者通知存储状态变化。
class TodoStore : Store {
    private(set) var todos = [Todo]()

    init() {
        ActionCreator.dispatcher.register(TodoAction.List.self) { (result) in
            switch result {
            case .Success(let value):
                self.todos.append(value)
                self.emitChange()
            case .Failure(let error):
                NSLog("error \(error)")
                break;
            }
        }
    }
}

步骤 3:在视图中订阅存储

  • 订阅存储来了解状态变化。
  • 从存储的公共接口获取结果。
let todoStore = TodoStore()
todoStore.subscribe { () -> () in
    for todo in todoStore.todos {
        plintln(todo.title)
    }
}

步骤 4:通过 ActionCreator 创建和调用动作

ActionCreator.invoke(TodoAction.Create())

高级

销毁回调

存储注册器处理程序到动作。分派器在集合中有处理程序引用。存储实例发布时,您需要释放处理程序引用。

class TodoStore {
    private var dispatchTokens: [DispatchToken] = []
    init() {
        dispatchTokens.append(
            ActionCreator.dispatcher.register(TodoAction.self) { (result) -> () in
              ...
            }
        )
    }

    func unregsiter() {
        for token in dispatchTokens {
            ActionCreator.dispatcher.unregister(token)
        }
    }
}

class TodoViewController {
  let store = TodoStore()
  deinit {
      store.unregister()
  }
}

`StoreBase` 包含注册/注销实用程序。您可以在覆盖自己的存储类时使用这些方法。

替换为您的自己的Dispatcher

覆盖ActionCreator的getter,您可以替换应用dispatcher。

class MyActionCreator: ActionCreator {
  static let ownDispatcher = YourOwnDispatcher()
  class MyActionCreator: ActionCreator {
    override class var dispatcher: Dispatcher {
        get {
            return ownDispatcher
        }
    }
}
class YourOwnDispatcher: Dispatcher {
    func dispatch<T: Action>(action: T, result: Result<T.Payload, T.Error>) {
        ...
    }
    func register<T: Action>(type: T.Type, handler: (Result<T.Payload, T.Error>) -> ()) -> String {
        ...
    }

    func unregister(dispatchToken: String) {
        ...
    }
    func waitFor<T: Action>(dispatchTokens: [String], type: T.Type, result: Result<T.Payload, T.Error>) {
        ...
    }
}

使用您自己的ErrorType代替NSError

您可以在您的Action上使用typealias分配自己的ErrorType

struct TodoAction: ErrorType {
    enum TodoError {
        case CreateError
    }
    struct Create : Action {
        typealias Payload = Todo
        typealias Error = TodoError
        func invoke(dispatcher: Dispatcher) {
            let error = TodoError.CreateError
            dispatcher.dispatch(self, result: Result(error: error))
        }
    }
}

FluxUtils

SwiftFlux包含基本的Store实现工具,类似于flux-utils

StoreBase

StoreBase提供基本的store实现。例如,注册/注销Action的回调等。

class CalculateStore: StoreBase {
    private(set) var number = 0

    override init() {
        super.init()

        self.register(CalculateActions.Plus.self) { (result) in
            switch result {
            case .Success(let value):
                self.number += value
                self.emitChange()
            default:
                break
            }
        }

        self.register(CalculateActions.Minus.self) { (result) in
            switch result {
            case .Success(let value):
                self.number -= value
                self.emitChange()
            default:
                break
            }
        }
    }
}

ReduceStore

ReduceStore通过reducer提供简化当前状态实现。reducer获取当前状态和Action的结果。reducer返回经过reduced的新状态。reducer应该是纯净的,并且不应该有副作用。ReduceStore扩展了StoreBase

class CalculateStore: ReduceStore<Int> {
    init() {
        super.init(initialState: 0)

        self.reduce(CalculateActions.Plus.self) { (state, result) -> Int in
            switch result {
            case .Success(let number): return state + number
            default: return state
            }
        }

        self.reduce(CalculateActions.Minus.self) { (state, result) -> Int in
            switch result {
            case .Success(let number): return state - number
            default: return state
            }
        }
    }
}

许可证

SwiftFlux按照MIT许可证发布。