まだ closure で消耗してるの？

# これはなに
**入門編です。**
非同期処理を実現するためには closure (Objective-C なら blocks) や delegate、observer などがあると思いますが、
これらを Rx で置き換えましょう。
なお、比較対象として closure と RxSwift に絞ります。これは私の体感として、Swift ではだいたい closure を使う場面が多いかなと思うからです。

### 環境
- Xcode 7.1.1 (Swift 2.1)
- Playground
- [RxSwift 2.0.0-beta.3](https://github.com/ReactiveX/RxSwift/tree/2.0.0-beta.3)

# 実現したいこと
ある整数を引数に渡したら非同期でその数を10倍して返してくれる 構造体A があり、それの結果をいろいろいじりたい、そういうのを考えます。
closure でやるといわゆる「コールバック地獄」に陥る事態も Rx ならばスッキリ書ける、という可読性向上を狙います。
モナドとか、関数型とか、そういう計算科学的なことは扱いません。

# closure おさらい
上記のことを closure で実現しようとすると以下になります。

```swift:Closure
struct closureA {
    func request(num: Int, response: (Int) -> ()) {
        response(num * 10)
    }
}

let a = closureA()
a.request(1) {
    print($0)    // 10
}
a.request(5) {
    print($0)    // 50
}
```

# RxSwift で書く
同じように RxSwift を使って書いてみます。`Observable<Element>` を使います。

```swift:RxSwift
struct observableA {
    func request(num: Int) -> Observable<Int> {
        return just(num * 10)
    }
}

let a = observableA()
a.request(1)
    .subscribeNext {
        print($0)    // 10
    }
    .dispose()
a.request(5)
    .subscribeNext {
        print($0)    // 50
    }
    .dispose()
```

`just(element: Element) -> Observable<Element>` であり、ここで Observable を生成しています。
そして `subscribeNext` で成功した時の値を取り出しています。
これならまだ closure で書いたほうがいいですね。

# 返ってきた結果を整理したい
## `Int` で返ってきたものを `String` に変換する

```:swift
let closure = closureA()
closure.request(1) {
    let str = String($0)
    print(str)               // "10"
}
```

```:swift
let observable = observableA()
observable.request(1)
    .map { String($0) }
    .subscribeNext {
        print($0)            // "10"
    }
    .dispose()
```

## 1以上の自然数だけを `String` に変換して出力したい

```:swift
let closure = closureA()
closure.request(1) { num in
    guard num > 0 else {
        return
    }
    let str = String(num)
    print(str)              // "10"
}
```

```:swift
let observable = observableA()
observable.request(1)
    .filter { $0 > 0 }
    .map { String($0) }
    .subscribeNext {
        print($0)
    }
    .dispose()
```

…どうでしょう？後処理が多くなればなるほど closure の中身が肥大化していきますね。すると本当に欲しいものがどこにあるか見つけづらくなっていくことかと思います。メソッドに切り出して後処理を投げるという手もありますがスコープを外れてしまうので可読性は？というところがあります。
一方 Rx の方は一番欲しいものである `subscribeNext` の中身は一切変わることなく、`filter`, `map` (`flatMap` もあります) でチェインすることで情報を整理することができます。

# コールバック地獄
さて話を変えます。
実践的な非同期処理では、「ある API を叩いた結果を使って別の API を叩く」や、「複数の API を同時に叩く」といったことがあります。
特に前者のような場合では「closure の中に closure を記述する」ということになり、非常に階層が深くなってしまいます。

```:swift
apiRequest.getUser("swift") { userData in
    apiRequest.follow(userData.id) { result in
        switch result {
        case .Success:
            print("follow success!")
        case .Failure:
            print("something is wrong...")
        }
    }
}
```

これを Rx の機能を使うとスッキリします。

```:swift
apiRequest.getUser("swift")
    .map { userData in
        apiRequest.follow(userData.id)
    }
    .switchLatest()
    .subscribe (
        onNext: {
            print("follow success!")
        },
        onError: {
            print("something is wrong...")
        },
        onCompleted: nil,
        onDisposed: nil
    )
    .dispose()
```

エラーかどうかの分岐もわざわざ `switch` を使わなくても `subscribe` の `onNext:`, `onError:` に振り分けることができるのも便利です。

# 実践編(Alamofire を Rx にしてみよう)
Swift のネットワークライブラリではもはやデファクトと言ってよい [Alamofire](https://github.com/Alamofire/Alamofire)。
これは標準では closure で結果を返すようになっています。

```:swift
Alamofire.request(.GET, "https://httpbin.org/get")
         .responseJSON { response in
             debugPrint(response)
         }
```
（[README](https://github.com/Alamofire/Alamofire#response-json-handler) より）

これを Observable で返すようにします。

まずはリクエストのためのインターフェースを切ります。

```:swift
func call(method: Alamofire.Method, url: String) -> Observable<AnyObject>
```
`<AnyObject>` の部分は [SwiftyJSON](https://github.com/SwiftyJSON/SwiftyJSON) や [Argo](https://github.com/thoughtbot/Argo) を使って `JSON` 型にしてもよいでしょう。

実装します。

```:swift
func call(method: Alamofire.Method, url: String) -> Observable<AnyObject> {
    return create { observer -> Disposable in
        Alamofire.request(method, url)
            .responseJSON { response in
                switch response.result {
                case .Success(let value):
                    observer.on(.Next(value))
                    observer.on(.Completed)
                case .Failure(let error):
                    observer.on(.Error(error))
                }
        }
        return AnonymousDisposable { }
    }
}
```

これで HTTP リクエストで Rx を使うことができます。

# まとめ
このように Rx を取り入れることでより読みやすいコードを書いていきましょう。