Edited at

ReactiveCocoa (RAC3.0) by Swift

More than 3 years have passed since last update.


はじめに

最近流行りのリアクティブプログラミング。ReactKitBondなどある中、ようやく老舗であるReactiveCocoaの仕様が固まりそうです。まだmasterリポジトリにはマージされていませんが、ひっそりとプレリリースされています。


試すには

Carthageからインストールするのが簡単でオススメです。ただし、Swift1.2対応のためxcode-selectにより使用するxcodebuildを変更してやる必要があります。


参考) CarthageでSwift 1.2に対応したライブラリをビルド

また、試すのであればswift-developmentブランチが最新であり良いと思います。Cartfilegithub "ReactiveCocoa/ReactiveCocoa" "swift-development"のように書き、carthage updateでOK。Mac用が必要なければ別途--platform iOSも追記してください。


Signal/Producer

簡単な例として、「UITextFieldに文字が入力されていたらボタンを有効にする」というのをRAC3.0使って書いてみます。


ViewController.swift


@IBOutlet weak var textField: UITextField!
@IBOutlet weak var button: UIButton!

lazy var dynamicProperty: DynamicProperty! = DynamicProperty(object: self.button, keyPath: "enabled")

override func viewDidLoad() {
super.viewDidLoad()

dynamicProperty <~ textField.rac_textSignal().toSignalProducer()
|> catch{ error in
return SignalProducer<AnyObject?, NoError>(value: "")
}
|> map{ value in
let str = value as! NSString
let can: Bool = str.length > 0
return can as AnyObject?
}
}


見ての通り、若干コード量が多く回りくどい印象があります。


ReactiveCocoa を Swift から使ってみた(2) KVO編でおっしゃっているように、rac_valuesForKeyPath()を使う事でKVOできるようになります。それを実現するため提供されているのがDynamicProperty<~です。<~は左辺に変更したいオブジェクトを配置し、右辺に変更起因となるシグナルを配置します。この例では右辺にSignalProducer<T, NSError>を配置しています。つまり、SignalProducer<T, NSError>からシグナルが発動するとそれがDynamicProperty (object.keyPath)に変更を加えるという流れです。


ちなみにSignalProducerRACSignal (cold signal)に相当し、SignalRACSignal (hot signal)に相当します。

また、気づいた方いらっしゃるかもしれませんが、ここではrac_textSignal()を使っています。これはobjective-Cで実装されたRACSignalを返す関数です。つまり、UIKitとやりとりを行う場合にはRACSignalを介す必要があります。


修正


●2015/3/22

コード中にcatchを追加しました。NSErrorNoErrorにキャストすると同時にシグナルのエラーをキャッチしてます。(catchを挟まないとバインディングできないのも不思議な感じですが)


●2015/3/23

ikesyoさん指摘の通り、catch部修正しました


最後に

最初にも書きましたが、まだプレリリースです。仕様は変わるかもしれません。ご注意ください。