官方文檔:
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最佳實踐以及指導如何實現自定義操作。