in in der 響應式編程
TRANSCRIPT
![Page 1: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/1.jpg)
in in der 響應式編程
張景隆 !
iOS Dev Club 蘋果貓咖啡
MOPCON 2014
![Page 2: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/2.jpg)
ReactiveCocoa
![Page 3: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/3.jpg)
Questions
•聽過 RAC
•很熟悉 RAC
•已經⽤用在專案上
![Page 4: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/4.jpg)
What is ReactiveCocoa
ReactiveCocoa is an open source library that brings
Functional Reactive Programming paradigm to
Objective-C. It was created by Josh Abernathy &
Justin Spahr-Summers in the development of GitHub
for Mac.
![Page 5: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/5.jpg)
What is Stream?
![Page 6: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/6.jpg)
![Page 7: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/7.jpg)
⼤大家覺得⽤用起來像是
![Page 8: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/8.jpg)
![Page 9: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/9.jpg)
但實際⽤用起來
![Page 10: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/10.jpg)
![Page 11: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/11.jpg)
看了 ReactiveCocoa 的 !
README
![Page 12: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/12.jpg)
![Page 13: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/13.jpg)
Agenda
•介紹 FRP
•事件與⾮非同步等問題
•介紹 ReactiveCocoa
• RAC 基礎
• RAC Example
• iOS Dev Club 社群介紹
![Page 14: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/14.jpg)
Appletone
• Perl
• Linux
• Java
• Ruby
• Objective-C
• Swift
![Page 15: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/15.jpg)
BTWCarbiichat CWMoney
![Page 16: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/16.jpg)
The Information Processing Cycle
![Page 17: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/17.jpg)
Imperative Programming
int x, y, z; x = 1; y = 1; z = x + y; // 1+1 y = 2; printf("%d", z); // z=2
![Page 18: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/18.jpg)
Reactive Programming
int x, y, z; x = 1; y = 1; z = x + y; // 1+1 y = 2; printf("%d", z); // z=3
![Page 19: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/19.jpg)
Functional Programming
NSMutableArray *arr = [NSMutableArray new]; for(int i=1; i<=3; i++) { [arr addObject:@(i * 5)]; }
ObjC:
map(1...3){ $0 * 5 }
Swift:
![Page 20: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/20.jpg)
Functional Reactive Programming
即 FP + RP 綜合兩種特性 !
賦予 RP 擁有許多 FP 的運算函⽰示
![Page 21: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/21.jpg)
Problems
• Target-Action
• Delegate
• Block
• Notifications
• KVO
!
•⽅方式太多
•缺乏⼀一致性
•商業邏輯分散
•難以整合各個事件
![Page 22: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/22.jpg)
One of the major advantages of RAC is that it provides a single, unified approach
to dealing with !
1. asynchronous behaviors, 2. including delegate methods, 3. callback blocks, 4. target-action mechanisms, 5. notifications, 6. and KVO.
RAC dealing with
![Page 23: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/23.jpg)
Why ReactiveCocoa?
![Page 24: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/24.jpg)
http://spin.atomicobject.com/2013/04/28/reactivecocoa/
Justin DeWind :
“ The Future of Cocoa Programming “
“ The brave new era for Objective-C “
Mattt Thompson :
http://nshipster.com/reactivecocoa/
![Page 25: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/25.jpg)
Terms
• RACSignal vs. RACSequence
• Cold or Hot Signals
![Page 26: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/26.jpg)
RACSignal vs. RACSequence
push-‐drivenpull-‐driven
![Page 27: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/27.jpg)
![Page 28: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/28.jpg)
Terms
• RACSignal vs. RACSequence
• Cold or Hot Signals
![Page 29: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/29.jpg)
Cold or Hot Signals
• Hot Signals
•按鈕事件
•事件即時通知
!
• Cold Signals
•網路事件
•不會⾺馬上有結果
![Page 30: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/30.jpg)
Macros
• RACObserve()
•建⽴立 RACSignal
•數值變動發動
!
!
• RAC()
•放在 assignment operator 的左邊
•綁定 RACSignal 給的數值
![Page 31: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/31.jpg)
RACObserve
!![RACObserve(self, username) subscribeNext:^(NSString *newName) { self.consoleLabel.text = newName; }];
RACSignal Subscriber
new value
![Page 32: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/32.jpg)
RAC
RAC(self.consoleLabel, text) = RACObserve(self, username);
RACSignal
binding
Value
![Page 33: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/33.jpg)
廣泛的使⽤用 KVO 為什麼不⽤用 KVO 就好?
![Page 34: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/34.jpg)
信號可被串接 KVO 不好⽤用
蘋果的⽂文件寫的很讚但是API設計的很爛
![Page 35: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/35.jpg)
Example I !
• rac_textSignal • map • avoiding retain cycles
![Page 36: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/36.jpg)
Example I
[self.textField.rac_textSignal subscribeNext:^(id x) { self.console.text = x; }];
RAC(self.console, text) = self.textField.rac_textSignal;
OR
![Page 37: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/37.jpg)
Example I
@weakify(self); [[self.textField.rac_textSignal map:^id(id value) { return [value uppercaseString]; }] subscribeNext:^(id x) { @strongify(self); self.console.text = x; }];
#import <RACEXTScope.h>
![Page 38: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/38.jpg)
Example II Login Demo
![Page 39: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/39.jpg)
![Page 40: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/40.jpg)
Example II
RACSignal *nameSignal = self.nameTextField.rac_textSignal; RACSignal *passSignal = self.passTextField.rac_textSignal; ! RAC(self.loginButton, enabled) = [RACSignal combineLatest:@[nameSignal, passSignal] reduce:^id(NSString *name, NSString *pass){ return @( ![name isEqualToString:@""] && ![pass isEqualToString:@""] ); }];
![Page 41: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/41.jpg)
Example III NSUserDefault
![Page 42: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/42.jpg)
Example III
! [[tokenSignal filter:^BOOL(NSString *token) { return [token chuzzle]?YES:NO; }]
RACSignal *tokenSignal = [[NSUserDefaults standardUserDefaults] rac_channelTerminalForKey:@"token"];
subscribeNext:^(NSString *token) { [self loadData]; }];
![Page 43: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/43.jpg)
Example IV !
AFNetworkReachabilityManager AFNetworking
![Page 44: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/44.jpg)
AFNetworkReachabilityManager *reachabilityManager = [AFNetworkReachabilityManager sharedManager]; RACSignal *isReachable = [RACObserve( reachabilityManager, networkReachabilityStatus) map:^(NSNumber *networkReachabilityStatus) { switch (networkReachabilityStatus.intValue) { case AFNetworkReachabilityStatusReachableViaWWAN: case AFNetworkReachabilityStatusReachableViaWiFi: return @YES; } return @NO; }];
![Page 45: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/45.jpg)
! RACSignal *myIPSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [manager GET:URLString parameters:nil success:^(AFHTTPRequestOperation *op, id response) { ! } failure:^(AFHTTPRequestOperation *op, NSError *e) { ! } ]; return nil; }];
NSString *URLString = @"http://ip.jsontest.com"; AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] init];
[subscriber sendNext:response]; [subscriber sendCompleted];
[subscriber sendError:e];
[myIPSignal subscribeNext:^(id response) { // NSLog(@"My IP => %@", response[@"ip"]); }];
![Page 46: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/46.jpg)
Example V
•檢查 網路狀態 以及 雲端伺服器 是否正常
•使⽤用者是否啟⽤用同步功能
•有待同步資料
•需綁定 FB Account
•可設定 WIFI 或 3G 底下同步
![Page 47: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/47.jpg)
![Page 48: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/48.jpg)
RACSignal *networkSignal = RACObserve(self, isNetworkReachable); RACSignal *cloudSignal = RACObserve(self, isUsedCloud); RACSignal *facebookSignal = RACObserve(self, isFacebookBinding); RACSignal *wifiOnlySignal = RACObserve(self, isWifiSyncOnly); ! NSArray *signals = @[networkSignal, cloudSignal, facebookSignal, wifiOnlySignal]; RACSignal *preparedSignal = [RACSignal combineLatest:signals reduce:^id (id network, id cloud, id facebook, id wifi){ return @([network boolValue] && [cloud boolValue] && [facebook boolValue] && [wifi boolValue]); }];
RACSignal *queueSignal = RACObserve(self, uploadQueue); [[[RACSignal combineLatest:@[preparedSignal, queueSignal]] filter:^BOOL(RACTuple *tuple) { return [[tuple first] boolValue]; }] subscribeNext:^(RACTuple *tuple) { // id task = [tuple second]; // do something ... }];
![Page 49: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/49.jpg)
RACSignal *queueSignal = RACObserve(self, uploadQueue); [[[RACSignal combineLatest:@[preparedSignal, queueSignal]] filter:^BOOL(RACTuple *tuple) { return [[tuple first] boolValue]; }] subscribeNext:^(RACTuple *tuple) { // id task = [tuple second]; // do something ... }];
deliverOn:[RACScheduler scheduler]]
[
Asynchronous Operation
![Page 50: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/50.jpg)
RACSignal+Operations.h
![Page 51: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/51.jpg)
Recap
• RACSequence & RACSignal 的差別
•熱信號 與 冷信號
•實⽤用的 Macros: RACObserve() & RAC()
•信號 的 建⽴立、訂閱、合併、轉換、過濾
•如何建⽴立⾮非同步的網路信號
![Page 52: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/52.jpg)
iOS Dev Club
![Page 53: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/53.jpg)
http://iosdev.club/
!iOS Dev Club 開發者聚會
iOS Dev Club 成⽴立於 2011 年 5 ⽉月。 我們是以 Facebook 的社團(groups)成⽴立,主要是為了在中部附近的 iOS App 設計開發同好,可以經常性碰⾯面互相學習的聚會,我們的地點都選擇在咖啡館,固定在每個⽉月最後⼀一週的星期六上午,每次都會安排主題分享研習。 !第⼀一年,我們在彰化的顏⽒氏牧場II舉辦。 第⼆二年,我們在台中的默契咖啡舉辦。 第三年,我們挑戰環島~ !因為每個⽉月中旬發出聚會訊息時,最常⾒見的歎息就是:為什麼不是在XXX? (XXX=請⾃自⾏行帶⼊入離⾃自⼰己居住熟悉或最近的城市) 於是第三年,我們分別在台北、新⽵竹、台中、⾼高雄辦了六場的 iOS Dev Club 開環島開發這聚會,我們到這幾個城市拜訪當地的 iOS 開發社團、專業的程式設計社團,互相交流也互相認識。 !第四年,我們來到了台中市⻯⿓龍井區的蘋果貓咖啡舉辦,我們除了在這裡每個⽉月舉辦⼀一次之外,也會陸續在每週都有研習課程加⼊入,請⼤大家密切注意我們在 Facebook 粉絲專⾴頁發佈的活動資訊。
![Page 54: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/54.jpg)
iOS Dev Club 環島開發聚#1 臺北 2013/5/26
![Page 55: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/55.jpg)
iOS Dev Club 環島開發聚#2 新⽵竹 2013/6/29
![Page 56: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/56.jpg)
iOS Dev Club 環島開發聚#3 ⾼高雄 2013/07/27
![Page 57: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/57.jpg)
iOS Dev Club 環島開發聚#6 臺北 2013/11/30
![Page 58: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/58.jpg)
WWDC 2014 研習分享 2014/06/28
![Page 59: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/59.jpg)
Apple 9/9 發表會後的設計須知 開發者的頭豈⽌止於⼤大
2014/09/27
![Page 60: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/60.jpg)
Apple 9/9 發表會後的設計須知 開發者的頭豈⽌止於⼤大
2014/09/27
![Page 61: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/61.jpg)
iOS Dev Club 資源
![Page 69: in in der 響應式編程](https://reader033.vdocuments.net/reader033/viewer/2022042615/55d5796fbb61eba42f8b4616/html5/thumbnails/69.jpg)