ゼロからはじめるRxSwift（Swift4）

# はじめに
これはRxSwift初心者がその概要をざっくり理解し、とりあえずRxSwiftで動くものを作るまでの記録です:muscle:
易しい記事やサンプルを探すのに苦労したのでまとめておきます。
Rx系の言語を使ったことがなく、まずは簡単に雰囲気を知りたいという人を対象としています。
（同じことをやろうとした場合の所要時間は2-3時間程度です）

↓最後にこれを作ります！
![rsSwift.gif](https://qiita-image-store.s3.amazonaws.com/0/112818/694e1ca7-14b4-5e74-7cde-6b4e1fe22949.gif)

# RxSwiftについて知る
以下の方法で調べました。

1. 「RxSwift」で検索して出てきた記事10-20つくらいにざっと目を通す
  * 繰り返し出てくるワードは重要語句としてチェック
  * 聞き慣れないワードばかりだが、脳を慣れさせていくイメージで流し読む
2. 初心者にもわかりやすそうな記事を5つくらいじっくり読む
 * 重要そうだけど分からないことは派生していくつか記事を読む 

## RxSwiftの概要
* Microsoftが2011年にリリースしたReactive ExtensionsのSwift版
* RxはFRP(Functional Reactive Programming：関数型リアクティブプログラミング)の一つで、その例がEXCEL
 * [リアクティブプログラミングへの理解がイマイチだったのでまとめてみた - UUUM攻殻機動隊(エンジニアブログ)](http://system.blog.uuum.jp/entry/%E3%83%AA%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%B8%E3%81%AE%E7%90%86%E8%A7%A3%E3%81%8C%E3%82%A4%E3%83%9E%E3%82%A4%E3%83%81%E3%81%A0%E3%81%A3) 
* メリット：値の変化の検知や非同期処理に強い
* デメリット：学習コストが高く、導入の敷居が高い

## 何度も出てきたワードたち
### ストリーム
<img width="830" alt="スクリーンショット 2018-09-07 14.19.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/112818/4199856f-adbe-3430-7ede-8a938e47a6bc.png">
by [アッテ開発の技術：Swift と RxSwift - Speaker Deck](https://speakerdeck.com/bricklife/atutekai-fa-falseji-shu-swift-to-rxswift)
この図が一番わかりやすかった！

### Observable
<img width="794" alt="スクリーンショット 2018-09-07 17.00.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/112818/11e1d346-82a6-2cd3-ed73-af7416a8fae5.png">
by [オブザーバーパターンから始めるRxSwift入門](https://qiita.com/k5n/items/17f845a75cce6b737d1e)
ストリームのマーブル図は、まさにこのObservableを表している。

### オブザーバーパターン
デザインパターンの一種。下記記事の出だしの文章がわかりやすかった。
[Rx入門 (2) - オブザーバーパターン - xin9le.net](http://blog.xin9le.net/entry/2011/12/10/153032)

>よくある例としては「データが変更されたときにUIを更新する」などが当てはまります。このようなとき、「データがUIを知っていて、UIの更新メソッドをそのまま呼び出す」というのは極めて汎用性が低い設計です。データはUIに依存するべきではないからです。「オブジェクトがクラスに依存せずに他のオブジェクトに状態変化を通知するにはどうすればよいか」。この問題をスマートに解決するために考えられたデザインパターンがオブザーバーパターンです。

### イベントの加工や合成
filter・map・merge・zip・reduceなど。

# 実際にRxSwiftを使ってみる
ここまででRxSwiftとは何かがだいたいわかったので、次は早速手を動かしていきます。
一番手っ取り早くRxSwiftを感じられそうな、**テキストフィールドを変更するとラベルに自動反映される**という機能を作ってみます。
※この程度だとRxSwiftを使わなくても実装できますが、今回は簡単にRxSwiftを試してみたいということでこちらを作ります。

## プロジェクトの作成
何でも大丈夫ですが、今回は`RxSwiftSample`という名前で作ります。

## CocoaPodsで導入
Carthageでも導入できるようですが、今回はCocoaPodsを使います。
RxSwiftとRxCocoaの両方をインストール！

```Podfile
target 'RxSwiftSample' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for RxSwiftSample
   pod 'RxSwift'
   pod 'RxCocoa'
end
```

## 画面を作る
ViewControllerにLabelとTextFieldそれぞれ1つずつ並べ、Outlet接続しておきます。
<img width="351" alt="スクリーンショット 2018-09-07 17.29.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/112818/4186ec3c-e840-f1a9-27bb-548105d20a49.png">

## RxSwiftを実装

コードはこちら↓。コピペしたら動きます。

```swift
import UIKit
import RxSwift
import RxCocoa


class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var textField: UITextField!
    
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        textField.rx.text.orEmpty
        .bind(to: label.rx.text)  
        .disposed(by: disposeBag)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
```

コードの中身を上から見ていくとこんな感じ（だと思う）↓

* DisposeBag()：観測状態からの解放を行う際に使う
* .orEmpty：受け取る値をStringに限定（String?からStringに変換）
* .bind：受け取った値とUIパーツへの関連付けをする
* .disposed：観測対象から除外する

これだけでTextFieldに入力した文字がLabelに自動反映されました:smile::tada:


# さいごに
実際にコードを書いてみて、「スッキリ書けるな」というのを実感することができました。
今後はMVVMなども並行して学びつつ、もっと理解を深めていきたいと思います。
この記事がゼロから学ぶ人のお役に少しでも立てば嬉しい限りです。

## 参考にさせて頂いた記事（上に出てきてないもののみ）
* [【Swift】RxSwiftを理解する｜新卒エンジニアの開発日記](https://fukatsu.tech/rxswift)
  * 全体像の理解に役立ちました:pray:
* [RxSwift触ってみた](https://qiita.com/jollyjoester/items/c4013c60acd453ea7248)
 * 今回のサンプルを作る際の参考にさせて頂きました:pray:
* [RxSwiftのexampleをコードで書く（その１）](https://qiita.com/nakagawa1017/items/f894b1ac051fab08b95d)
 * Swift4で書かれていて役立ちました:pray:
* [RxSwiftでの実装練習の記録ノート（前編：Observerパターンの例とUITableViewの例）](https://qiita.com/fumiyasac@github/items/90d1ebaa0cd8c4558d96)
 * 詳細まで丁寧に書かれており役立ちました:pray: