Krunoslav Zaher
是
RxFeedback
的作者。他也是
RxSwift
的
创始人
以及
ReactiveX 组织
的核心成员。他有 16 年以上的编程经验( VR 引擎,BPM 系统,移动端应用程序,机器人等),最近在研究响应式编程。
RxSwift
最简单的架构
typealias Feedback<State, Event> = (Observable<State>) -> Observable<Event>
public static func system<State, Event>(
initialState: State,
reduce: @escaping (State, Event) -> State,
feedback: Feedback<State, Event>...
) -> Observable<State>
已经发生 -> Event
即将发生 -> Request
执行 Request -> Feedback loop
首先系统行为被明确声明出来,然后在调用 subscribe 后开始运作 => 编译时就保证了不会有“未处理状态”
大多数逻辑是 纯函数,可以通过 xCode 调试器调试,或者将命令打印出来
适用于任何级别
- 应用程序(state 被储存在数据库中,CoreData, Firebase, Realm)
- view controller (state 被储存在 system 操作符)
- 在 feedback loop 中(feedback loop 中 调用另一个 system 操作符)
- 容易做依赖注入
- Reducer 是 纯函数,只需调用他并断言结果即可
- 伴随 附加作用 的测试 -> TestScheduler
- 可以处理循环依赖
- 完全从附加作用中分离业务逻辑
Observable.system(
initialState: 0,
reduce: { (state, event) -> State in
switch event {
case .increment:
return state + 1
case .decrement:
return state - 1
scheduler: MainScheduler.instance,
feedback:
bind(self) { me, state -> Bindings<Event> in
let subscriptions = [
state.map(String.init).bind(to: me.label.rx.text)
let events = [
me.plus.rx.tap.map { Event.increment },
me.minus.rx.tap.map { Event.decrement }
return Bindings(
subscriptions: subscriptions,
events: events
这是一个简单计数的例子,只是用于演示 RxFeedback 架构。
State
系统状态用 State 表示:
typealias State = Int
- 这里的状态就是计数的数值
Event
事件用 Event 表示:
enum Event {
case increment
case decrement
- increment 增加数值事件
- decrement 减少数值事件
当产生 Event 时更新状态:
Observable.system(
initialState: 0,
reduce: { (state, event) -> State in
switch event {
case .increment:
return state + 1
case .decrement:
return state - 1
scheduler: MainScheduler.instance,
feedback: ...
- increment 状态数值加一
- decrement 状态数值减一
Feedback Loop
将状态输出到 UI 页面上,或者将 UI 事件输入到反馈循环里面去:
Observable.system(
initialState: 0,
reduce: { ... },
scheduler: MainScheduler.instance,
feedback:
bind(self) { me, state -> Bindings<Event> in
let subscriptions = [
state.map(String.init).bind(to: me.label.rx.text)
let events = [
me.plus.rx.tap.map { Event.increment },
me.minus.rx.tap.map { Event.decrement }
return Bindings(
subscriptions: subscriptions,
events: events
- 将状态数值用
label
显示出来
- 将增加按钮的点击,作为增加数值事件传入
- 将减少按钮的点击,作为减少数值事件传入
CocoaPods 是一个 Cocoa 项目的依赖管理工具。你可以通过以下命令安装他:
$ gem install cocoapods
将 RxFeedback 整合到项目中来,你需要在 Podfile
中指定他:
pod 'RxFeedback', '~> 3.0'
然后运行以下命令:
$ pod install
Carthage 是一个分散式依赖管理工具,他将构建你的依赖并提供二进制框架。
你可以通过以下 Homebrew 命令安装 Carthage:
$ brew update
$ brew install carthage
将 RxFeedback 整合到项目中来,你需要在 Cartfile
中指定他:
github "NoTests/RxFeedback" ~> 3.0
运行 carthage update
去构建框架,然后将 RxFeedback.framework
拖入到 Xcode 项目中来。由于 RxFeedback
对 RxSwift
和 RxCocoa
有依赖,所以你也需要将 RxSwift.framework
和 RxCocoa.framework
拖入到 Xcode 项目中来。
Swift Package Manager 是一个自动分发 Swift 代码的工具,他已经被集成到 Swift 编译器中。
一旦你配置好了 Swift 包,添加 RxFeedback 就非常简单了,你只需要将他添加到文件 Package.swift
的 dependencies
的值中。
dependencies: [
.package(url: "https://github.com/NoTests/RxFeedback.swift.git", majorVersion: 1)
与其他架构的区别
- Elm - 非常相似,feedback loop 用作 附加作用, 而不是
Cmd
, 要执行的 附加作用 被编码到 state 中,并且通过 feedback loop 完成请求
- Redux - 也很像,不过采用 feedback loops 而不是 middleware
- Redux-Observable - observables 观察状态,与视图和状态之间的 middleware
- Cycle.js - 一言难尽 :),请咨询 @andrestaltz
- MVVM - 将状态和 附加作用 分离,而且不需要 View
下一节将用 Github Search 来演示如何使用 RxFeedback。