美文网首页
ReactiveCocoa使用实践

ReactiveCocoa使用实践

作者: 佐伊Joey | 来源:发表于2019-03-01 17:23 被阅读0次

    使用RACChannel进行双向数据绑定

    RACChannel 非常适合于视图和模型之间的双向绑定,在对方的属性或者状态更新时及时通知自己,达到预期的效果;我们可以使用 ReactiveCocoa 中内置的很多与 RACChannel 有关的方法,来获取开箱即用的 RACChannelTerminal ,当然也可以使用 RACChannelTo 通过 RACKVOChannel 来快速绑定类与类的属性。

    RACChannelTo(self.viewModel, username) = self.usernameTextField.rac_newTextChannel;
    

    定时器,可以代替Timer

    //这里要加takeUntil条件限制一下否则当控制器pop后依旧会执行
    [[[RACSignal interval:2 onScheduler:[RACScheduler mainThreadScheduler]] takeUntil:self.rac_willDeallocSignal ] subscribeNext:^(id x) {
        
        NSLog(@"每两秒执行一次");
        
    }];
    

    RAC通知写法

    //代替通知
    //takeUntil会接收一个signal,当signal触发后会把之前的信号释放掉
    [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id x) {
        
        NSLog(@"键盘弹出");
        
    }];
    

    多个请求,统一处理结果

    - (void)testRACSignal
    {
        // 创建信号A
        RACSignal *signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            // 处理信号
            NSLog(@"%s 创建信号A", __FUNCTION__);
            // 发送数据
            [subscriber sendNext:@"热门商品"];
            return nil;
        }];
        // 创建信号B
        RACSignal *signalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            // 处理信号
            NSLog(@"%s 创建信号", __FUNCTION__);
            // 发送数据
            [subscriber sendNext:@"最新商品"];
            
            return nil;
        }];
        
        // RAC:就可以判断两个信号有没有都发出内容
        // SignalsFromArray:监听哪些信号的发出
        // 当signals数组中的所有信号都发送sendNext就会触发方法调用者(self)的selector
        // 注意:selector方法的参数不能乱写,有几个信号就对应几个参数
        // 不需要主动订阅signalA,signalB,方法内部会自动订阅
        [self rac_liftSelector:@selector(updateUIWithHot: new:) withSignalsFromArray:@[signalA,signalB]];
    }
    - (void)updateUIWithHot:(NSString *)hot new:(NSString *)new
    {
        NSLog(@"%s hot = %@ , new = %@", __FUNCTION__, hot ,new);
    }
    

    重试

    -(void)retry{
        __block int flag = 0;
        
        RACSignal *signal =  [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            
            if (flag == 4){
                [subscriber sendNext:@"1"];
                [subscriber sendCompleted];
            }else{
                flag ++;
                NSLog(@"flag= %d",flag);
                [subscriber sendError:[NSError errorWithDomain:@"myerror " code:100 userInfo:nil]];
            }
            return nil;
        }];
        [[signal retry:5]subscribeNext:^(id x) {
            NSLog(@"xxxx =%@",x);
        }];
        
    }
    

    发送请求,捕获错误处理

    例子:如果在请求返回token过期,需要重新获取token再继续重新请求

    // 发送请求
    RACSignal *requestSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        NSString *url = @"http://httpbin.org/ip";
        [[AFHTTPRequestOperationManager manager] GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            [subscriber sendNext:responseObject];
            [subscriber sendCompleted];
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            // token 过期
            [subscriber sendError:error];
        }];
        return nil;
    }];
    
    [[requestSignal catch:^RACSignal *(NSError *error) {
        // error捕获
        return [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            // 模拟获取token请求
            double delayInSeconds = 1.0;
            dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
            dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
                [subscriber sendNext:@YES];
                NSLog(@"subscriber sendNext...");
                [subscriber sendCompleted];
            });
            return nil;
        }] concat:requestSignal];   //RACSignal拼接,获取token之后再重新请求
    }] subscribeNext:^(id x) {
        // 请求正常返回的数据
        NSLog(@"next =%@",x);
    } completed:^{
        NSLog(@"completed");
    
    }];
    

    搜索请求

    使用节流器throttle,在0.3秒内使用最后一个输入text进行请求

    [[[[[[self.textField.rac_textSignal throttle:0.3] distinctUntilChanged] ignore:@""] map:^id(id value) {
        NSLog(@"value =%@",value);
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            
            //  network request
            [subscriber sendNext:value];
            [subscriber sendCompleted];
            
            return [RACDisposable disposableWithBlock:^{
                
                //  cancel request
            }];
        }];
    }] switchToLatest] subscribeNext:^(id x) {// 如果不switchToLastest 则返回一个signal
        
        NSLog(@"x = %@",x);
    }];
    

    相关文章

      网友评论

          本文标题:ReactiveCocoa使用实践

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