美文网首页iOSiOS进阶指南iOS开发
RACCommand在项目中的实战运用和理解

RACCommand在项目中的实战运用和理解

作者: turmando | 来源:发表于2016-08-22 19:36 被阅读3110次

    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方法等待你的发现,至于如何更好的利用这个利器,相信你也有几分的了解了,接下来的就需要自己不断的摸索更多神奇而又强大的方法了.

    文献参考

    RACCommand英文文档

    相关文章

      网友评论

      • 疯狂超人_:RACCommand 我可以理解成在控制器要把值传到viewModel中不, 然后
        RACSignal 我可以理解成在viewModel 中的值返回给控制器不.
        这样理解有没有错 .

      本文标题:RACCommand在项目中的实战运用和理解

      本文链接:https://www.haomeiwen.com/subject/zpjgsttx.html