LoginSignup
40
38

More than 5 years have passed since last update.

SwiftBondの作者さんが作った新ライブラリ「ReactiveKit」を使ってみた

Last updated at Posted at 2015-11-19

SwiftBondの作者さんが作った新ライブラリ「ReactiveKit」を使ってみた

SwiftBondの作者である@srdanrasicさんが、ReactiveKitというライブラリを開発していました。

この記事を投稿した(2015/11)時点で、スター数が30弱しかないです。

READMEを少し見てみたところ、ほぼSwiftBondですが、OperationというRxのObservableのようなものが追加されているようです。その他も少し変わっているっぽい?

ということで検証してみました。

※ 今回検証するバージョンは「1.0.4」です。

Observable

Basic

SwiftBondと同じですね。

let value1 = Observable(1)
let value2 = Observable(2)

print(value2.value) // => 2

value1.bindTo(value2) // バインド

print(value2.value) // => 1

value1.next(7)

print(value2.value) // => 7

UIKit

ReactiveUIKitをimportすることでUIKitのObservableプロパティを使用することも可能です。ViewのプロパティとViewModelのプロパティのバインドするのに便利です。

textField.rText.bindTo(label)
textField.rText.bindTo(viewModel.emailAddress)

Collection

配列はObservableCollectionを使います。

var list = ObservableCollection([Int]())

list.observe{e in
    print("array: \(e.collection), inserts: \(e.inserts)")
}

list.append(10) // => array: [10], inserts: [0]
list.append(10) // => array: [10, 10], inserts: [1]

Operation

さらっと見た感じRxのObservableと同じようなものっぽいです。

Operationの作成

ReactiveXのcreateメソッドと同じです。Operation構造体のイニシャライザにオブザーバーがセットされた時の処理を記述したクロージャを渡します。返り値にはDisposableType?を指定する必要があります。BlockDisposableを使うとdisposeされた時の処理をかけるっぽい。

let operation = Operation {(observer: OperationObserver<NSData, NSError>) in
    let request = Alamofire.request(.GET, url: url).response { _, _, data, error in
        if let error = error {
            observer.failure(error)
        } else {
            observer.next(data)
            observer.success()
        }
    }
    return BlockDisposable {
        request.cancel()
    }
}

let disposable = operation.observe(on: Queue.main.context){event in
    switch event{
    case .Next(let value):
        print(value)
    case .Failure(let error):
        print("エラーハンドリング \(error)")
    case .Success:
        print("Success")
    }
}

上記のコードは、オブザーバーがセットされた時にAlamofireでAPIを叩いて結果が返ってきた時にオブザーバーにイベントを伝える例です。リクエストキャンセルするには

disposable.dispose()

とすれば良いです。

うーん、めっちゃRxSwiftに似ているなぁ。

StreamTypeとObservableとOperation

ObservableはObservableTypeに適合しており、OperationはOperationTypeに適合しています。さらに、ObservableTypeとOperationTypeは共にStreamTypeに適合しています。

つまり、ObservableやOperationに使えるメソッドはStreamTypeのProtocol Extensionで実装されているものがほとんどです。

メソッドは、Rxでよく見るmapやfilterやthrottleやzipなどなどです。

ReaciveKit = SwiftBond + RxSwift って感じなのかなーと個人的には思っています。
ライブラリのコード読んでいると基本的にSwiftBondのコードを流用しつつ新しい要素取り入れていってる感じでした。

おまけ

StreamType ProtocolのExtensionで実装されているzipメソッドが凄かった

@warn_unused_result
public func zip<A: StreamType, B: StreamType, C: StreamType, D: StreamType, E: StreamType, F: StreamType, G: StreamType, H: StreamType, I: StreamType, J: StreamType, K: StreamType>
  ( a: A, _ b: B, _ c: C, _ d: D, _ e: E, _ f: F, _ g: G, _ h: H, _ i: I, _ j: J, _ k: K) -> Stream<(A.Event, B.Event, C.Event, D.Event, E.Event, F.Event, G.Event, H.Event, I.Event, J.Event, K.Event)>
{
  return zip(a, b, c, d, e, f, g, h, i, j).zipWith(k).map { ($0.0, $0.1, $0.2, $0.3, $0.4, $0.5, $0.6, $0.7, $0.8, $0.9, $1) }
}
40
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
38