【RxSwift入門】普段使ってるこんなんもRxSwiftで書けるんよ

`RxSwift`取り入れたけどまだ慣れてない人向け
なんかのヒントになれば幸いです。

# Delegate
RxSwift使ってたら`自前Delegate`は`closure`は作らなくなってくると思います

```swift:普通の書き方 
class SampleViewController: UIViewController, SampleViewDelegate {
    @IBOutlet weak var view: SampleView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    // MARK: SampleViewDelegate
    func sendMessage(message: String) {
        print("Did select : \(message)")
    }
}

class SampleViewDelegate {
    func sendMessage(message: String)
}

class SampleView: UIView {
    weak var delegate: SampleViewDelegate?
    
    private func didSelect() {
        delegate?.sendMessage("message")
    }
}
```

```swift:Rxを取り入れた書き方
import RxSwift
class SampleViewController: UIViewController {
    @IBOutlet weak var view: SampleView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.rx_message
            .subscribeNext { [ unowned view] message in
                print("Did select : \(message)")
            }
            .addDisposableTo(rx_disposeBag)
    }
}

class SampleView: UIView {    
    // ここでは`PublishSubject`を使っていますが、
    // イベントの取得だけでなく、値の保持をしたいなら`Variable`を使うのがいいです
    let rx_message = PublishSubject<String>()
    
    private func didSelect() {
        rx_message.on(.Next("message"))
    }
}
```
## Delegate Extensionを作ってみる

RxSwiftの記述を参考に、DelegateメソッドをObserverで返せるようにしてみます
例としてUINavigationControllerのExtensionをあげます

```swift
extension UINavigationController {

    var rx_willShowViewController: Observable<(UIViewController, Bool)> {
        return rx_delegate.observe("navigationController:willShowViewController:animated:")
            .map { a in
                // 引数に渡したい値を返します
                return (a[1] as! UIViewController, a[2] as! Bool)
        }
    }
    var rx_didShowViewController: Observable<(UIViewController, Bool)> {
        return rx_delegate.observe("navigationController:didShowViewController:animated:")
            .map { a in
                // 引数に渡したい値を返します
                return (a[1] as! UIViewController, a[2] as! Bool)
        }
    }
}
```
# RxSwiftに用意されてる便利なObserverたち
ここからは意外となんでもあるな、というものを紹介します。

`RxSwift`は結構`Observer`が用意されています。
主によく使ったもののみの紹介とさせていただきます。ここにないのもたくさんあります。
コード書く際に、まずは`Observer`がないか試してみるといいと思います。

## ボタンのタップイベント
```swift:普通の書き方 
class SampleViewController: UIViewController {
    @IBOutlet weak var button: UIButton!
    private var flag = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        button.addTarget(self, action: #selector(SampleViewController.onClickPushButton), forControlEvents: .TouchUpInside)
    }

    func onClickPushButton(sender: UIButton) {
        if flag {
            print("did tap")
        }
    }
}
```
```swift:Rxを取り入れた書き方
import RxSwift

class SampleViewController: UIViewController {
    @IBOutlet weak var button: UIButton!
    private var flag = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        button.rx_tap
            .filter {[unowned self] self.flag}
            .subscribeNext {
                print("did tap")
            }
            .addDisposableTo(button.rx_disposeBag)
    }
}
```
`UIControlEvents`もあります

```swift:Rxを取り入れた書き方
import RxSwift
class SampleViewController: UIViewController  {
    
    @IBOutlet weak var button: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        button.rx_controlEvent(UIControlEvents.TouchUpInside)
            .subscribeNext { [unowned self] in
                print("button TouchUpInside!")
            }
            .addDisposableTo(button.rx_disposeBag)
    }
}
```

## NSNotificationCenter
```swift:普通の書き方
class SampleViewController: UIViewController {
    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "notificationObserve:", name: AVPlayerItemDidPlayToEndTimeNotification, object: playerItem)
    }
    
    func notificationObserve(notification: NSNotification) {
        print("notificationObserve : \(notification)")
    }
}
```
```swift:Rxを取り入れた書き方
import RxSwift
class SampleViewController: UIViewController {
    
    deinit {
        // rx_disposeBagは開放されるのでremoveの必要なし
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NSNotificationCenter.defaultCenter().rx_notification(AVPlayerItemDidPlayToEndTimeNotification, object: nil)
            .subscribeNext { [ unowned view] notification in
                print("rx_notification : \(notification)")
            }
            .addDisposableTo(rx_disposeBag)
    }
}
```
## UIScrollView. contentOffset

```swift:普通の書き方
class SampleViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
    }
    
    func scrollViewDidScroll(scrollView: UIScrollView) {
        print("scrollViewWillBeginDragging \(scrollView.contentOffset)")
    }
}
```
```swift:Rxを取り入れた書き方
class SampleViewController: UIViewController {
    
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.rx_contentOffset
            .subscribeNext { [weak self] contentOffset in
                // contentOffset値の変化時に取得
                print("rx_contentOffset : \(contentOffset)")
            }
            .addDisposableTo(rx_disposeBag)
    }
}
```
## Gesture

```swift:普通の書き方
class SampleViewController: UIViewController  {
    
    @IBOutlet weak var view: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let tapGesture = UITapGestureRecognizer(target: self, action: "tapGesture:")
        view.addGestureRecognizer(tapGesture)
    }
    
    func tapGesture(gesture: UIGestureRecognizer) {
        print("gestureのtapイベントを取得")
    }
}
```

```swift:Rxを取り入れた書き方
class SampleViewController: UIViewController  {
    
    @IBOutlet weak var view: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let tapGesture = UITapGestureRecognizer()
        
        tapGesture.rx_event
            .map(void) // 引数使わない場合はmapしてしまう
            .subscribeNext {
                print("gestureのtapイベントを取得")
            }
            .addDisposableTo(view.rx_disposeBag) // viewが持つ`rx_disposeBag`を使うと開放時にわかりやすい
        
        view.addGestureRecognizer(tapGesture)
    }
}
```
## NSURLSession

多くなってきたのでちょっと駆け足で。
↓取得して`Observer`にして返すのも便利です

```swift
private func getData() -> Observable<NSData> {
    let url = NSURL(string: "https://xxxx")!
    return NSURLSession.sharedSession()
        .rx_data(NSURLRequest(URL: url))
        .take(1)
}
```
## UISlider
```swift:
slider.rx_value.asObservable()
    .subscribeNext { value in
        print("Sliderの値変更時に\(value)取得")
    }
    .addDisposableTo(slider.rx_disposeBag)
```

---
以上になります。
書き慣れてない文章でごめんなさい。
自分もまだまだ人のを真似ることしかできないので知らない部分だらけです。
思いついたらどんどん足していきます。

なにかありましたらお気軽にご教授ください。
なにかの参考にさればさいわいです。