Swift
RxSwift

RxSwiftをサクッと勉強してみた

More than 1 year has passed since last update.

今更感が否めないのですが、勉強会をさせていただく機会をいただきRxSwiftを勉強してみました。

RxSwiftについて

RxSwiftのRxとはReactive Extensionsの略称で、Swift以外にもJava、JS、Scalaなどの言語でRxを取り扱う事ができます。

ReactiveX

Rxを用いると非同期処理やイベント処理などを宣言的に記述することができるようになります。
モバイルアプリをより良いプロダクトにしていくには、ユーザーのUIを妨げにならない非同期処理やイベントや時間等のトリガーに応じて様々な処理をインタラクティブに実現することが不可欠です。
ただし、そういった記述が重なっていくと往々にしてコードが煩雑になり目を背けたくなるように地獄ViewControllerを生み出してしまった経験がある人は少なく無いと思います。
RxSwiftはそういった記述をより簡潔に実現できるようにする為のライブラリです。


ちなみに学習をする前のRxSwiftの印象はこんな感じでした。

FirstImpression.swift
// 生成したUIButtonに対して
// aが発生したらthisを
// bが発生したらthatを実行

let button = UIButton(...)
button.aHappen { doThis() }
      .bHappen { doThat() }

view.addSubview(button)

オブジェクトのプロパティとして、対象のオブジェクトにAやBという事象が発生した際にどういう挙動をさせるかという事をそのまま記述できる的なノリかと。
確かに様々なパターンの挙動を一つに集約することができてスッキリしそう!!

という事で、実際にはどのような事が実現できるのか触ってみましょう。

導入

pod 'RxSwift'
pod 'RxCocoa'

をPodfileに記述、

pod install
で必要なライブラリをインストールできます。

Cocoapodsを使用していない人はこちらから

実際に触ってみる

導入の際にRxSwiftとは別にRxCocoaというライブラリをインストールしましたが、これはUIKitの様々なクラスで使用できるプロパティをextensionとしてすでに定義してくれています。

RxCocoa

実際にUIButtonを例にRxCocoaの一例を見てみましょう

UIButton+Rx.swift(一部抜粋)
extension Reactive where Base: UIButton {

    /// Reactive wrapper for `TouchUpInside` control event.
    public var tap: ControlEvent<Void> {
        return controlEvent(.touchUpInside)
    }
}

これを実際に使用してみると以下のようになります。

ButtonRxTry.swift
let button = UIButton()

button.rx.tap
            .subscribe(onNext: { [weak self] in
                doSomething()
            })
            .addDisposableTo(disposeBag)

Rxを取り扱う上で理解が必須な概念は
ObservableType
Subscribe
の2つです。

ざっくりと説明すると、
ObservableTypeには何を監視するかを設定し、
Subscribeには何を行うかを設定します。

ObservableTypeによっては戻り値が設定されていることもあり、
subscribeのパラメーターのクロージャー内でその値にアクセスすることができます。

次はUITextFieldを例にして記述してみます。

TextFieldTry.swift
let label = UILabel()
let textField = UITextField()

textField.rx.text
            .subscribe(onNext: { [weak self] text in
                label.text = text
            }).addDisposableTo(disposeBag)

先程のUIButtonのtapがObservableTypeの子クラスであるControlEvent<Void>だったのに対して、
UITextFieldのtextはControlProperty<String?>
となっているので、subscribeからString?にアクセスをすることができます。

ソース
https://github.com/takashi9314/RxTest