ReactiveCocoa勉強会関西　メモ書き


2014/07/26 in Hatena kyoto.

## 初めてのReactiveCocoa

@tinpay さん , Chatworkモバイルチーム

http://www.tinpay.com/my_first_rac-2578.html

初めてReactiveCocoa 見た時→どうしろと…

そんな僕がどうやって実装したか。

### ReactiveCocoa とは？

ObjCで関数型リアクテゥブプログラミングをサポート

使い方: pod "ReactiveCocoa"

#### リアクティブプログラミングとは？

命令形

```
a = 1;
b = a + 2;
a = 3;
print(b); => 3
```

リアクティブプログラミングだと

```
a = 1;
b = a + 2;
a = 3;
print(b); => 5
```

#### MVVM とは？

- Model
- View
- ViewModel


ViewController と Model の間に ViewModel を噛ます形

(要はCocoaBinding みたいなもの？)(←CocoaBindingはViewとModelだが、ViewControllerとModelをやるわけではないから、ちょっと違うっぽい)


ViewController::viewDidLoad にViewModelとの連結部分を書く？形なので、ViewModelとViewController の役割を分けて書くことができる。


### メリット・デメリット

#### メリット

- ViewControllerがスッキリした
 - 処理がViewModelに書くので肥大化しなくなった
- テストが書きやすい
 - ビジネスロジックはModelに書いている。
 - UIに依存しない書き方ができる
- 一時変数が無くなった

#### デメリット

- 難しい
 - 今まで書いたほうが速いんじゃね…
- Signal を連鎖し過ぎると見にくい
 - 保守が大変じゃね…？

### まとめ


- 難しい
- 直感的じゃない（なれてない）けど
- 短くなる
- 頑張っていこう


##  ゆるやかなReactiveCocoa

@ninjinkun フリマアプリ


### 今こだまグリーン車が安い
9500縁で東京⇔新大阪。4時間かかるけど勉強時間にいいよ


### 注意

勉強しながら資料作ってるので、わりと間違ってると思うのであてにしないでください。

### なぜ今ReactiveCocoa か？

- アプリの複雑化

FrilのLike

一覧画面→商品単品の画面→Likeをつける→一覧画面でLikeも表示


#### FRP (関数型リアクティブプログラミング)

FRP is programming with asynchronous in streams.?

- .Net から来た
- akka とか Yampa RxExtentions, RAC, RxJava RxJS, react,..

FRP 
- The Reactive Manifesto
- Event-Driven
- Scalabel
- Resilient
- Responsive

#### FRP 用途

- サーバサイドでも使える
 - チャットや動画配信など
- Client
 - SNS, Chat とかAPIコールするアプリ・ゲームなど

### スマホはイベントだらけ

- GPS/Notification など…

### Fablic の RAC ポリシー

- RACにロックインされるような実装は避ける
 - RACオブジェクトをモジュール間のインターフェースにまたがないようにする

- テキストのValidation
- delegate rapper
- KVO wapper

#### MVVM とは

- View Model を噛ませる
- Point: View と ViewController を同じ View であるとみなしている。

### 僕が考えるMVVM

- Mutableな物はVMに集める
- JSON からのObjectはImmutableに
- VM に対するUnitTest を書く

### Frilの商品VM

商品一覧APIと商品詳細APIを合わせたVMを持たせてやっている

### 資料？
- The... 見過ごした
 - これっぽい https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
- Principels of Reactive Programming
 -  Scala のMartinセンセイが
- Reactive Programming in iOS
 - 100p ぐらい

### よくわかってない事

- ほかのFRPフレームワークとRACの用語対応
- Class FRP. SIgnal Function
- アニメーションとの相性が悪い説

### まとめ

- RCの段階的な採用
 - Validation /delegate wrapper
- MVVC のゆるやかな以降
- まだまだRAC中毒ではない


## 実践TwitterAPI+RC

@atsusy

フリーランス / C/C++/C#/ObjC/Titatinum Mobile(主にモジュール)

Twitter REST API の search/tweet を使った検索アプリ。
RCをどんな感じで使えばいいかとかとか

### アプリ

- キーワード検索

#### Pods

- ReactiveCocoa
- SDWebImage
- Mantle
- NSDate+TimeAgo

#### サンプル

https://github.com/atsusy/RACTweetSearcher/


### MVVM


- ViewController 
 - Fat View Controller を避ける
- ViewModel はテスト可しやすい
 - UI に非依存

#### MVVM の関係

- View(VIewController)
 - Bindgin / invocation(Command) => ViewModel
- Model
 - Notification => viewModel
- ViewModel
 - Notification => View
 - Notification => Model

#### Binding

Readonly/ WriteOnly /Read,Write がある

#### Command

- ViewController から ViewModelが持つCommandを呼び出す
- 実行可否や実行中の状態を持つ
- UIButton/UIRefreshCntrolと連動
 - self.someButton.rac_command = command;

#### ViewCotnroller の役割

- 画面遷移
- アニメーション
- ViewModelに対するリアクション

#### ViewModel の役割

- 表示内容の保持
- 状態管理
- 変換処理
　- Model <-> ViewModel の変換
 - 日付、数値を表示仕様へ
- Model のCRUD(ネット通信), ロジック実行

#### クラス構成

- TweetSearchViewController => ViewModel => TweetSearchViewModel
 - TweetSearchViewModel => tweet (TweetSearchTweetViewModel)
 - TweetSearchViewModel? => Client(TweetSearchClient)
 - TweetSearchTweetViewModel  => base TweetModel 
 - TweetSearchViewModel ..?


### 非同期処理

できるだけRCに依存したくない…

#### RACSIgnalSupport

Signale で非同期処理をする形？


### コマンド

Signal をラップして、状態を持ってるようなやつ。

#### 定期処理

テーブルの表示変更（1秒間隔でリロード)

RACSiganl interval:RACScheduler:] をつかえる

ただスクロールしてると、カクつくので他の方法

[[siganl throttle:INFINITY valuePassingTest:] subscribleNext:]

subscribleNext で更新処理をして、valuePassingTest: で更新するかしないかの条件文を書く

### いいと思う

- リアクティブな振る舞いを宣言的に記述
 - コードが集約、KVOやdelegateに比べて
- 非同期処理が簡単に扱える
 - 副作用を簡単に追加
 - エラー処理も簡単

### ダメだなぁと思う

- ハードル高い
- signal 設計が難しい


## var RAC3 = ReactiveCocoa + Swift

@ikesyo さん

ReactiveCocoa コミッター


### 今日はSwiftベースのRC3.0 の紹介

Xcode6 beta4時点の内容で。

事後のSwift言語仕様とかAPI変更で変わる可能性有り


突然のSwift →　その日の朝にRCイベント@GitHubでRxSwift を実験的にやってたら、RC3.0に。
そして元にあった3.0はClosedになり、3.0になる変更点などは移行。


### New Concepts

- Generics Support (swift)
- Producer
- Consumer
- Signal
- SignalingProperty
- Propise
- Action

3.0 になって新しいのが増えて、一から勉強しなおしな所あるけど頑張って…

#### Generics Support

型パラメータはサポート( Tuple がサポートされたので )


#### Producer

- Cold RACSignal Event Stream
- Consumer をアタッチしてイベントを Produce する

Arrayの要素100個あって、ループで回して50個目で止めたいとか、同期的な処理ができなかったので設計仕様の変更がある。

- Consumer が自分のところに来たら、Consumer毎にEventを作る？

#### Consumer

- like id<RACSubscriber> subscriver

-Sink プロコトルのputにEvent<T>でラップした値を返す
 - public func put(event:Event<T>){}
 - 従来の -sendNext: の代わり

補足

- evidence という型チェックにより、特定型パラメータを持つProducerのみ呼ぶことができるようにする
 - swift の struct / enum を Racに投げるので、enum などを返すとかむりくり言語機能に合わせる形である


#### Signal

今までの RAC Signal とは違う

- Hot RACSIgnal : Behaviour in other FRP
- Completed/Error による終了はなく、現在値を持っている
- T -> () のクロージャがオブサーバ SinkOf<T>になって、observeする

#### SignalingProperty

値の変更をSIgnalとして通知することができるプロパティ用オブジェクト

- SwiftのClass != NSObject の時、KVOがないので、外部から値の変更監視ができないので、自分から通知できる仕組みを作る必要がある。
- func __conversion() で変換後の型で、自分の型から返還後の型の通知？
 - ラップしてることを知らせないために、swiftの機能を使う

#### Promis

- 単一の値を生成する遅延タスク
- Producer のような Event Stream ではないので複数の値を通知したりしない

- 値は public let signal: Signal<T?> でSignal として参照できる
 - resolve 前: nil? esolve後:T

#### Action

RACCommandの置き換え

- Input から Output を返すアクション
- 最近の変更で、UI以外のところでも動かすことができるようになった
- アクションの実行結果（Output）はPromis を返す
- RACシグナルを内包したSignalを返すのが、仕様変更により、前のアクションの実行結果から次のアクションにチェーンにつなげることができるようになった。


RAC3.0はこんな感じ



## [LT] RAC用クラス拡張の作り方


@yonekawa さん。会計フリーからのぞみを乗って来ました。

2月あたりからRAC使ってリリースしてる。


### RACのいいところ

Binding が多くていいな。

自分でCategory書けばいいんだよ。

1. SVProgressHUD に追加してみたり。
2. NJKWebViewProgress に追加してみたり。
1. UIBUtton+MeijinSupport (1秒間に15回ボタン連打するやつ)

デモ

https://github.com/yonekawa/RACSupportExamples


## [LT] ReactiveCocoa と NSMutableArray

@at_aka さん from Chatwork

（タイトル聞き逃したから、違うかも）

### トランプゲームサンプル


- RAC の基本
 - `RAC(self.label, text) = RACObserve(self.viewModel, numString)`

- NSMutableArray が鬼門

https://github.com/ataka/rac-card

- 変化を追わない（追加された/削除された物を知る)方法ならいけるんでない。

## [LT] 全然Reactiveじゃない話

@yashigani さん in Hatena


### Parse.com の話

Hanena で新入社員はwebアプリをつくｒ（ｒｙ）あれYoじゃね？

- DeviceTokenの管理がだるい
 - アカウントとかログインとかとか

- Parseは BaaS
 - DBとかPushNotificationとかを代行
 - 前 Facebook に買収
- DeviceTOken の管理が楽
 - PFInstallation に登録
 - development/production によって使い分けをしてくれる
- DataStore が ModelClass ベース
 - ブラウザ上で定義/確認/編集できる
- SDKがいたれりつくせり
 - JS/REST API / iOS / WindowsPhone/ Android

### とにかく気が効きすぎ！

以上です


## [LT] RC でのフロー制御

@matuyuji さん From FenrirInc.

IIJMiOのAPIを叩いてみた

1. クーモンデータ
2. パケットデータ
1. JSONデータをマージする
1. OAuth2の認証(トークン鳥)


JSON => AFNetworking+RACExtensionsで。
Merge => Racのconcat:でして、map: でなんとかかんとか

## [LT] Observer Pattern

@cockscomb さん from Hatena

- GoFの23のデザパタの一つ
- Model変化をViewに通知する素朴なパターン


### Observer Patter

- Cocoa+ObjC => KVO
- Java => java.util.ovserver / Java.beans.ovserver
- swift => ?
 - ObjC の KVO は dynamic(getter/setterが差し替わる)
 - swift なら static じゃない
 - コンパイルタイムに解決するんじゃない
 - そのうちわかる

hatena では現在smart phone エンジニアを積極採用中です。