in in der 響應式編程

69
in in der 響應式編程 張景隆 iOS Dev Club 蘋果貓咖啡 MOPCON 2014

Upload: -

Post on 20-Aug-2015

2.685 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: in in der 響應式編程

in in der 響應式編程

張景隆 !

iOS Dev Club 蘋果貓咖啡

MOPCON 2014

Page 2: in in der 響應式編程

ReactiveCocoa

Page 3: in in der 響應式編程

Questions

•聽過 RAC

•很熟悉 RAC

•已經⽤用在專案上

Page 4: in in der 響應式編程

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 響應式編程

What is Stream?

Page 6: in in der 響應式編程
Page 7: in in der 響應式編程

⼤大家覺得⽤用起來像是

Page 8: in in der 響應式編程
Page 9: in in der 響應式編程

但實際⽤用起來

Page 10: in in der 響應式編程
Page 11: in in der 響應式編程

看了 ReactiveCocoa 的 !

README

Page 12: in in der 響應式編程
Page 13: in in der 響應式編程

Agenda

•介紹 FRP

•事件與⾮非同步等問題

•介紹 ReactiveCocoa

• RAC 基礎

• RAC Example

• iOS Dev Club 社群介紹

Page 14: in in der 響應式編程

Appletone

• Perl

• Linux

• Java

• Ruby

• Objective-C

• Swift

Page 15: in in der 響應式編程

BTWCarbiichat CWMoney

Page 16: in in der 響應式編程

The Information Processing Cycle

Page 17: in in der 響應式編程

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 響應式編程

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 響應式編程

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 響應式編程

Functional Reactive Programming

即 FP + RP 綜合兩種特性 !

賦予 RP 擁有許多 FP 的運算函⽰示

Page 21: in in der 響應式編程

Problems

• Target-Action

• Delegate

• Block

• Notifications

• KVO

!

•⽅方式太多

•缺乏⼀一致性

•商業邏輯分散

•難以整合各個事件

Page 22: in in der 響應式編程

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 響應式編程

Why ReactiveCocoa?

Page 24: in in der 響應式編程

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 響應式編程

Terms

• RACSignal vs. RACSequence

• Cold or Hot Signals

Page 26: in in der 響應式編程

RACSignal vs. RACSequence

push-­‐drivenpull-­‐driven

Page 27: in in der 響應式編程
Page 28: in in der 響應式編程

Terms

• RACSignal vs. RACSequence

• Cold or Hot Signals

Page 29: in in der 響應式編程

Cold or Hot Signals

• Hot Signals

•按鈕事件

•事件即時通知

!

• Cold Signals

•網路事件

•不會⾺馬上有結果

Page 30: in in der 響應式編程

Macros

• RACObserve()

•建⽴立 RACSignal

•數值變動發動

!

!

• RAC()

•放在 assignment operator 的左邊

•綁定 RACSignal 給的數值

Page 31: in in der 響應式編程

RACObserve

!![RACObserve(self,  username)  subscribeNext:^(NSString  *newName)  {          self.consoleLabel.text  =  newName;  }];

RACSignal Subscriber

new value

Page 32: in in der 響應式編程

RAC

RAC(self.consoleLabel, text) = RACObserve(self, username);

RACSignal

binding

Value

Page 33: in in der 響應式編程

廣泛的使⽤用 KVO 為什麼不⽤用 KVO 就好?

Page 34: in in der 響應式編程

信號可被串接 KVO 不好⽤用

蘋果的⽂文件寫的很讚但是API設計的很爛

Page 35: in in der 響應式編程

Example I !

• rac_textSignal • map • avoiding retain cycles

Page 36: in in der 響應式編程

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 響應式編程

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 響應式編程

Example II Login Demo

Page 39: in in der 響應式編程
Page 40: in in der 響應式編程

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 響應式編程

Example III NSUserDefault

Page 42: in in der 響應式編程

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 響應式編程

Example IV !

AFNetworkReachabilityManager AFNetworking

Page 44: in in der 響應式編程

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 響應式編程

! 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 響應式編程

Example V

•檢查 網路狀態 以及 雲端伺服器 是否正常

•使⽤用者是否啟⽤用同步功能

•有待同步資料

•需綁定 FB Account

•可設定 WIFI 或 3G 底下同步

Page 47: in in der 響應式編程
Page 48: in in der 響應式編程

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 響應式編程

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 響應式編程

RACSignal+Operations.h

Page 51: in in der 響應式編程

Recap

• RACSequence & RACSignal 的差別

•熱信號 與 冷信號

•實⽤用的 Macros: RACObserve() & RAC()

•信號 的 建⽴立、訂閱、合併、轉換、過濾

•如何建⽴立⾮非同步的網路信號

Page 52: in in der 響應式編程

iOS Dev Club

Page 53: in in der 響應式編程

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 響應式編程

iOS Dev Club 環島開發聚#1 臺北 2013/5/26

Page 55: in in der 響應式編程

iOS Dev Club 環島開發聚#2 新⽵竹 2013/6/29

Page 56: in in der 響應式編程

iOS Dev Club 環島開發聚#3 ⾼高雄 2013/07/27

Page 57: in in der 響應式編程

iOS Dev Club 環島開發聚#6 臺北 2013/11/30

Page 58: in in der 響應式編程

WWDC 2014 研習分享 2014/06/28

Page 59: in in der 響應式編程

Apple 9/9 發表會後的設計須知 開發者的頭豈⽌止於⼤大

2014/09/27

Page 60: in in der 響應式編程

Apple 9/9 發表會後的設計須知 開發者的頭豈⽌止於⼤大

2014/09/27

Page 61: in in der 響應式編程

iOS Dev Club 資源

Page 62: in in der 響應式編程

http://iosdev.club

Page 63: in in der 響應式編程

https://www.facebook.com/ios.dev.club

Page 64: in in der 響應式編程

https://www.youtube.com/user/iOSDevClub

Page 65: in in der 響應式編程

https://github.com/iOSDevClub

Page 66: in in der 響應式編程

有問題 請上 iOS Dev Club

https://www.facebook.com/ios.dev.club

Page 67: in in der 響應式編程

http://taichung.iiiedu.org.tw/swift.html

Page 68: in in der 響應式編程

Thanks for coming !

@[email protected]

Page 69: in in der 響應式編程