title: RACCommand在項目中的實戰運用和理解
date: 2016-08-09
categories: iOS
tags:
-ReactiveCocoa
{% cq %}
RACCommand作為RAC比較重要的一個部分,其作用就是得到信號指令觸發動作執行,一般涉及到UI交互操作.那在項目里我們要怎樣巧妙的使用這個利器呢?
{% endcq %}
RACCommand的你需要了解的
兩種創建方式
#1
_orderCreatCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
return nil;
}];
}];
#2
RACSignal *isEnableSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
return nil;
}];
_orderCreatCommand = [[RACCommand alloc] initWithEnabled:isEnableSignal signalBlock:^RACSignal *(id input) {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
return nil;
}];
}];
屬性和方法的解析
調用執行成功返回信號的信號,主線程執行
@property (nonatomic, strong, readonly) RACSignal *executionSignals;
調用執行當前信號是否正在執行返回@(NO),主線程執行
@property (nonatomic, strong, readonly) RACSignal *executing;
默認情況下返回@NO信號,但只有一下兩種情況會返回@YES 1.上面第二種創建RACCommand的時候就給isEnableSignal賦值為@YES的時候 2.allowsConcurrentExecution屬性設置為 NO并且這個信號正在執行中. 主線程執行
@property (nonatomic, strong, readonly) RACSignal *enabled;
是否允許多個RACCommand同時執行。
@property (atomic, assign) BOOL allowsConcurrentExecution;
執行RACCommand的時候發送獲取的error信號
@property (nonatomic, strong, readonly) RACSignal *errors;
調用RACCommand,input為executionSignals的訂閱者發送的值
- (RACSignal *)execute:(id)input;
開始著手項目實戰
項目功能需求講解一:
某訂單確認頁面
images
點擊提交訂單按鈕
在VC中代碼:
這里訂閱從ViewModel返回的最終信號
//點擊提交訂單
[[self.commitOrderButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
STRONG
[[self.confirmOrderViewModel.orderCreatCommand execute:finalParames]
subscribeNext:^(NSDictionary *x) {
self.commitOrderButton.enabled = YES;
if ([self.confirmOrderViewModel.payWay isEqualToString:pay_downLine]{
//貨到付款處理...
} else {
//在線支付處理...
}
} error:^(NSError *error) {
[SVProgressHUD showErrorWithStatus:@"網絡錯誤~"];
}];
}];
在ViewModel中代碼:
創建command,在input獲取從VC中調用的execute傳來的參數,返回一個信號.信號包裹著提交訂單網絡請求的數據返回給下一個訂閱著.
- (RACCommand *)orderCreatCommand{
_orderCreatCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(NSMutableDictionary *params) {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[SVProgressHUD showWithStatus:@"提交訂單..."];
[XNBaseRequest HTTPPostWithUrl:URL_SX(XNRequestOrderCreat)
Parames:parames
commplete:^(id result) {
[subscriber sendNext:payDict];
});
}
failure:^(NSError *error) {
[subscriber sendError:error];
}];
return nil;
}];
}];
return _orderCreatCommand;
}
項目功能需求講解二:
某訂單支付頁面
images
點擊確認支付按鈕
同樣獲取按鈕點擊事件做你想做的事
[[self.CheckStandViewModel.payCommand execute:@"1"] subscribeNext:^(NSNumber *isSuccess) {
self.CheckStandViewModel.isOrderSuccess = isSuccess.boolValue;
} error:^(NSError *error) {
[SVProgressHUD showErrorWithStatus:@"網絡錯誤~"];
}];
同樣在ViewModel里創建Command
... 你可以做你想自己的數據處理,在這我都不展示了
- (RACCommand *)payCommand{
WEAK
_payCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(NSString *payType) {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
STRONG
[SVProgressHUD showWithStatus:@"前往支付..."];
...
[XNBaseRequest HTTPPostWithUrl:url
Parames:parames
commplete:^(id result) {
...
[subscriber sendNext:@(NO)];
[subscriber sendCompleted];
failure:^(NSError *error) {
[subscriber sendError:error];
}];
return nil;
}];
}];
return _payCommand;
}
總結
在RAC中萬物皆信號,所以你需要更多的去理解信號作為一種流的方式存在.還有更多RACCommand方法等待你的發現,至于如何更好的利用這個利器,相信你也有幾分的了解了,接下來的就需要自己不斷的摸索更多神奇而又強大的方法了.