官方文档:
http://reactivecocoa.io/reactiveswift/docs/latest/index.html
实战项目:
https://github.com/JornWu/ZhiBo_Swift.git
一、什么是ReactiveSwift
ReactiveSwift
提供了可组合的、声明性和灵活的围绕“随时间推移的值流”这种宏观概念而创建的实体。
这些实体从根本上是一种监视行为,可用于统一地代表通常Cocoa上和通用的编程模式。如:代理
、回调闭包
、通知
、控制行为
、事件响应者链
、未来/承诺
和KVO
。
因为这些不同的机制可以用相同方式来都表示。可以把要处理的事情,和监听的事情的代码放在一起,这样非常方便我们管理,就不需要跳到对应的方法里。非常符合我们开发中高聚合,低耦合的思想。
二、核心Reactive实体
1、Signal:单向事件流
Signal
的所有者对事件流持有单方面的控制。观察者可以在任何时候注册接收他们所感兴趣的事件。但是这些观察对事件流或者其所有者都没side effect
。
let channel: Signal<Program, NoError> = tvStation.channelOne
channel.observeValues { program in ... }
2、Event:事件流的基本传输单位
一个Signal
可以拥有任意数量的携带着值的Event
,这些事件最后跟随着一个特别原因的终止事件。
3、SignalProducer:创建值流的延后工作
SignalProducer
延后工作,其输出表示为值流,直到它被启动。每个调用启动SignalProducer
,就会创建一个新的Signal
,并且延后工作被随后调用。
let frames: SignalProducer<VideoFrame, ConnectionError> = vidStreamer.streamAsset(id: tvShowId)
let interrupter = frames.start { frame in ... }
interrupter.dispose()
4、Lifetime:限制观察的范围
当在观察Signal
或SignalProducer
中,如果不再有对象在观察它们时,其就没必要继续发出值。细想流媒体:只要你停止观看这个视频一次,这个流就会自动通过提供一个Lifetime
来关闭。
class VideoPlayer {
private let (lifetime, token) = Lifetime.make()
func play() {
let frames: SignalProducer<VideoFrame, ConnectionError> = ...
frames.take(during: lifetime).start { frame in ... }
}
}
5、Property:一个总持有值的可视的容器
Property
是一个可看得到其变化的变量。换句话说,其是一个比Signal
更有保证的值流,其最新的值总是可用并且这个流永远不会失败。
它就像视频播放的持续更新的当前时间偏移 - 播放总是在任何时候偏移一定的时间,并且随着播放继续,它将会通过播放逻辑被更新。
let currentTime: Property<TimeInterval> = video.currentTime
print("Current time offset: \(currentTime.value)")
currentTime.signal.observeValues { timeBar.timeLabel.text = "\($0)" }
6、Action:一系具有预设事件的行为
当被输入调用时,Action
将输入和最新状态应用于预设事件,并将输出推送给任何有兴趣的方。它就像一台自动售货机 - 在选择了插入硬币的选项后,机器会处理订单并最终输出您想要的零食。
请注意,整个过程是相互排斥的 - 您不能同时为两个客户服务。
// Purchase from the vending machine with a specific option.
vendingMachine.purchase
.apply(snackId)
.startWithResult { result
switch result {
case let .success(snack):
print("Snack: \(snack)")
case let .failure(error):
// Out of stock? Insufficient fund?
print("Transaction aborted: \(error)")
}
}
// The vending machine.
class VendingMachine {
let purchase: Action<Int, Snack, VendingMachineError>
let coins: MutableProperty<Int>
// The vending machine is connected with a sales recorder.
init(_ salesRecorder: SalesRecorder) {
coins = MutableProperty(0)
purchase = Action(state: coins, enabledIf: { $0 > 0 }) { coins, snackId in
return SignalProducer { observer, _ in
// The sales magic happens here.
// Fetch a snack based on its id
}
}
// The sales recorders are notified for any successful sales.
purchase.values.observeValues(salesRecorder.record)
}
}
7、参考文献
有关ReactiveSwift中的概念和官方介绍的更多详细信息,请查看以下文档:
Framework Overview
ReactiveSwift官方介绍和实用程序的行为和建议用例的综述。
Basic Operators
提供组合和变换这些元方法的操作的综述。
Design Guidelines
ReactiveSwift元方法的规定和ReactiveSwift最佳实践以及指导如何实现自定义操作。