ReactiveCocoa
Swift

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部修正しました

最後に

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