美文网首页
ReactiveCocoa使用篇

ReactiveCocoa使用篇

作者: LearningCoding | 来源:发表于2017-03-27 15:13 被阅读24次
/**
     *  FRP(Functional Reactive Programming):函数响应式编程
     *  a = 2, b = 2; c = a + b; 可以得到c = 4,当b = 3时,c自动编程5;叫做响应式编程
     */
    /**
     *  RACSignal使用  信号就是数据流
    *   可以把信号想象成水龙头,只不过里面不是水,而是玻璃球(value),直径跟水管的内径一样,这样就能保证玻璃球是依次排列,不会出现并排的情况(数据都是线性处理的,不会出现并发情况)。水龙头的开关默认是关的,除非有了接收方(subscriber),才会打开。这样只要有新的玻璃球进来,就会自动传送给接收方。可以在水龙头上加一个过滤嘴(filter),不符合的不让通过,也可以加一个改动装置,把球改变成符合自己的需求(map)。也可以把多个水龙头合并成一个新的水龙头(combineLatest:reduce:),这样只要其中的一个水龙头有玻璃球出来,这个新合并的水龙头就会得到这个球。
     */
    __weak typeof(self)weakSelf = self;
    // 在UITextField category里面添加了属性,textfield可以直接用,当输入框选中编辑时,将给订阅者发送信号
    [self.usernameTF.rac_textSignal subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    // filter 过滤信号的内容 满足条件的内容才能被返回
    [[self.passwordTF.rac_textSignal filter:^BOOL(id value) {
        NSString *str = value;
        return str.length > 3;
    }] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    // map对信号的内容进行编辑,将编辑后的信号返回
    // RAC(对象,属性) = 信号 : 将对象的属性修改为信号的内容
    RAC(self.usernameTF, backgroundColor) = [self.usernameTF.rac_textSignal map:^id(NSString *value) {
        return [value boolValue] ? [UIColor whiteColor] : [UIColor yellowColor];
    }];
    
    RAC(self.passwordTF, backgroundColor) = [self.passwordTF.rac_textSignal map:^id(NSString *value) {
        return [value boolValue] ? [UIColor whiteColor] : [UIColor yellowColor];
    }];
    
    RACSignal *usernameSignal = [self.usernameTF.rac_textSignal map:^id(NSString *value) {
        return @(value.length >= 6);
    }];
    RACSignal *passwordSignal = [self.passwordTF.rac_textSignal map:^id(NSString *value) {
        return @(value.length >= 6);
    }];
    // combineLatest:@[,]  合并信号  reduce:^id(,)将信号的内容编辑,将编辑后的内容的信号返回
    RACSignal *signUpActiveSignal = [RACSignal combineLatest:@[usernameSignal, passwordSignal] reduce:^id(NSNumber *usernameValid, NSNumber *passwordValid){
        return @([usernameValid boolValue] && [passwordValid boolValue]);
    }];
    
    [signUpActiveSignal subscribeNext:^(NSNumber *x) {
        weakSelf.loginButton.backgroundColor = [x boolValue] ? [UIColor redColor] : [UIColor blueColor];
    }];
    // rac_signalForControlEvents :UIControl category,触发后发送信号
    // doNext:信号发送后,执行;
    // flattenMap :先map 在flatten 将信号里的信号返回
    [[[[self.loginButton rac_signalForControlEvents:(UIControlEventTouchUpInside)] doNext:^(id x) {
        weakSelf.loginButton.backgroundColor = [UIColor yellowColor];
    }] flattenMap:^id(id value) {
//        return [weakSelf.viewModel loginSignalWithUsername:weakSelf.usernameTF.text andPassword:weakSelf.passwordTF.text];
        // raccommand可以发送数据 execute返回信号 可以subscribeError: completed:接收
        return [weakSelf.viewModel.raccommand execute:@{@"username" : @"username", @"password" : @"password"}];
    }] subscribeNext:^(NSNumber *x) {
        BOOL success = [x boolValue];
        if (success) {
            
        }
        NSLog(@"sign in resule:%@", x);
        weakSelf.loginButton.backgroundColor = [UIColor redColor];
    }];

- (RACSignal *)signInSignal {
    
    // 自定义信号,sendNext:给订阅者发送信号; sendCompleted:信号完成,信息流结束
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [RACManager signInWithUsername:self.usernameTF.text password:self.passwordTF.text complete:^(BOOL success) {
            [subscriber sendNext:@(success)];
            
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [subscriber sendNext:@"false"];
            });
            
            [subscriber sendCompleted];
        }];
        return nil;
        
    }];
    
}

- (RACSubject *)signInSignalWithSubject {
    // RACSubject是racsignal的子类
    RACSubject *subject = [RACSubject subject];
    
    [RACManager signInWithUsername:self.usernameTF.text password:self.passwordTF.text complete:^(BOOL success) {
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [subject sendNext:@(success)];
            
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [subject sendNext:@(success)];
            });
            [subject sendCompleted];
        });
        
    }];
    
    return subject;
}

viewmodel.h

- (RACCommand *)raccommand;
- (RACSignal *)loginSignalWithUsername:(NSString *)username andPassword:(NSString *)password;

viewmodel.m

self.raccommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(NSDictionary *input) {
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [self signInWithUsername:input[@"username"] password:input[@"password"] complete:^(BOOL result) {
                if (result) {
                    [subscriber sendNext:@(result)];
                } else {
                    [subscriber sendError:[[NSError alloc] init]];
                }
            }];
            return nil;
        }];
    }];

- (RACSignal *)loginSignalWithUsername:(NSString *)username andPassword:(NSString *)password {
    
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        [self signInWithUsername:username password:password complete:^(BOOL success) {
            
            [subscriber sendNext:@(success)];
            [subscriber sendCompleted];
        }];
        return nil;
    }];
    
}
// 模拟请求数据库
- (void)signInWithUsername:(NSString *)username password:(NSString *)password complete:(void (^)(BOOL))complete {
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if ([username isEqual:@"username"] && [password isEqual:@"password"]) {
            complete(true);
        } else {
            complete(false);
        }
    });
}

相关文章

网友评论

      本文标题:ReactiveCocoa使用篇

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