iOS RAC 初探

也研究了下RAC,这个的确一时很难学进去,都是各种流的做法。流来流去,信号机制。废话不说,直接上代码---也可以去我github点击打开链接

#import "ViewController.h"
#import "RWDummySigninService.h"
#import <ReactiveCocoa/ReactiveCocoa.h>
@interface ViewController ()
{
    UITextField *_text;

    UITextField *_User;
    UITextField *_Code;

    UIButton *_sig;

}
@property(strong,nonatomic) RWDummySigninService *signInService;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

//    _text = [[UITextField alloc]init];
//    _text.frame = CGRectMake(100, 100, 100, 100);
//    [self.view addSubview:_text];

//
//    [_text.rac_textSignal subscribeNext:^(id x) {
//
//        NSLog(@"%@",x);
//    }];

    //过滤:filter(应付复杂的情况)
    //rac_textSignal: 是RAC为UITextField添加的category,只要usernameTextField的值有变化,这个值就会被返回(sendNext)-------创建并返回一个信号的文本字段
    //subscribeNext:   加了下面这段代码后,signal就处于Hot的状态了,block里的代码就会被执行。如果不加就处于cold阶段,什么也不会发生。
    [[_text.rac_textSignal filter:^BOOL(id value) {
        NSString *text = value;
        return text.length >3;

    }]subscribeNext:^(id x) {
        NSLog(@"%@",x);

    }];
    ;

    //映射---将NSString 映射为NSNumber
    //新添加的map操作使用提供的block来转换事件数据。对于收到的每一个next事件,都会运行给定的block,并将返回值作为next事件发送。在上面的代码中,map操作获取一个NSString输入,并将其映射为一个NSNumber对象,并返回。
//    [[[_text.rac_textSignal map:^id(NSString *text) {
//
//        return @(text.length);
//    }]
//    filter:^BOOL(NSNumber *length) {
//        return [length intValue] >3;
//    }]
//    subscribeNext:^(id x) {
//        NSLog(@"%@",x);
//    }];

        _User = [[UITextField alloc]init];

        _User.frame = CGRectMake(100, 100, 100,30);

    _User.borderStyle = UITextBorderStyleLine;

        [self.view addSubview:_User];

    _Code = [[UITextField alloc]init];

    _Code.frame = CGRectMake(100, 150, 100,30);

    _Code.borderStyle = UITextBorderStyleLine;

    [self.view addSubview:_Code];

    _sig = [UIButton buttonWithType:UIButtonTypeCustom];
    _sig.frame = CGRectMake(100, 250, 50, 30);
    _sig.backgroundColor = [UIColor redColor];
    [self.view addSubview:_sig];

    //对每个输入框的rac_textSignal应用了一个map(映射成NSNumber)转换。输出是一个用NSNumber封装的布尔值。然后利用收到的值来改变颜色
    RACSignal *validUsernameSignal = [_User.rac_textSignal map:^id(NSString *text) {
        //return @([self isValidUsername:text]);
        return nil;

    }];

    RACSignal *validPasswordSignal = [_Code.rac_textSignal map:^id(NSString *text) {
        //return @([self isValidPassword:text]);

        return nil;

    }];

    //一种方法
//    [[validPasswordSignal map:^id(NSNumber *passwordvalid) {
//        return [passwordvalid boolValue] ?[UIColor clearColor]:[UIColor yellowColor];
//
//    }] subscribeNext:^(UIColor *color) {
//        _Code.backgroundColor = color;
//    }];

    //这是更好的写法
    RAC(_Code,backgroundColor) = [validPasswordSignal map:^id(NSNumber  *passwordValid) {
        return [passwordValid boolValue] ? [UIColor clearColor]:[UIColor yellowColor];

    }];

    //下一步是转换这些信号,从而能为输入框设置不同的背景颜色。基本上就是,你订阅这些信号,然后用接收到的值来更新输入框的背景颜色
    //RAC宏允许直接把信号的输出应用到对象的属性上。RAC宏有两个参数,第一个是需要设置属性值(NILVALUE)的对象,第二个是属性名(TARGET)。每次信号产生一个next事件,传递过来的值都会应用到该属性上。
    //RAC_(TARGET, KEYPATH, NILVALUE)
    //这个宏是最常用的,RAC()总是出现在等号左边,等号右边是一个RACSignal,表示的意义是将一个对象的一个属性和一个signal绑定,signal每产生一个value(id类型),都会自动执行
    RAC(_User,backgroundColor) = [validUsernameSignal map:^id(NSNumber *passwordValid) {
        return [passwordValid boolValue] ? [UIColor clearColor] : [UIColor yellowColor];
    }];

    //组合信号
    //使用了combineLatest:reduce:方法来组合validUsernameSignal与validPasswordSignal最后输出的值,并生成一个新的信号。每次两个源信号中的一个输出新值时,reduce块都会被执行,而返回的值会作为组合信号的下一个值。

    //注意:RACSignal组合方法可以组合任何数量的信号,而reduce块的参数会对应每一个信号。

    RACSignal *signUpActiveSignal = [RACSignal  combineLatest:@[validUsernameSignal,validPasswordSignal ] reduce:^id(NSNumber *usernameValid, NSNumber *passwordValid){

        return @([usernameValid boolValue] && [passwordValid boolValue]);

    }];

    //这将信号连接到按钮的enabled属性。处于hot状态
//     [signUpActiveSignal subscribeNext:^(NSNumber *signupActive) {
//
//         _sig.enabled = [signupActive boolValue];
//
//         NSLog(@"11");
//     }];

    //从按钮的UIControlEventTouchUpInside事件中创建一个信号,并添加订阅以在每次事件发生时添加日志。
//    [[_sig rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
//
//        NSLog(@"Button clicked");
//    }];

    //使用map方法将按钮点击信号转换为登录信号。订阅者简单输出了结果。
    [[[_sig rac_signalForControlEvents:UIControlEventTouchUpInside] flattenMap:^RACStream *(id value) {
        return [self signInSignal];
    }] subscribeNext:^(id x) {

        NSLog(@"Sign in result: %@", x);
    }];

}

-(RACSignal *)signInSignal
{
    //createSignal:方法用于创建一个信号。描述信号的block是一个信号参数,当信号有一个订阅者时,block中的代码会被执行。

    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [self.signInService signInWithUsername:_User.text password:_Code.text complete:^(BOOL success) {
            [subscriber sendNext:@(success)];
            [subscriber sendCompleted];

        }];

        return nil;

    }];

}

@end

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-07 08:54:52

iOS RAC 初探的相关文章

Appium IOS 自动化测试初探

手机平台的自动化测试工具很多,之前研究过了安卓和苹果的原生自动化测试框架,经一些同事介绍,貌似Appium是个不错的工具. 想记录一下研究的结果,也算是篇干货的文章 在网上也看了一些视频,个人认为这个自动化测试的特点就是 1. 多编程语言支持 相对于传统的IOS UIautomation只能支持js语言,Appium起到了一个翻译的作用,它其实是一个CS架构,服务器和IOS模拟器或真机直接通讯,客户端和服务器之间用HTTP协议进行交互,所以客户端用什么语言其实不重要.下面会有一个python编程

iOS开发初探篇——UITabBarController

概述 导航在iOS开发中的重要性就不多说了.通常UINavigationController会结合UITabBar一起使用,此初探篇是单独对UINavigationBar及UINavigationController做一个比较全面的基础使用. 本文主要内容如下: 1.UINavigationBar的基础使用 2.UINavigationController的基础使用 UINavigationBar的基础使用 UINavigationBar一般位于屏幕的顶端.继承自

iOS开发初探篇——表视图中的MVC运用

概述 本初探篇为本人学习iOS开发中的一个总结系列,为工作和业余学习中遇到的初级问题的一个初步探究.本文初探的内容是MVC设计模式在表视图中的应用.首先感谢博主KC写的精彩博文. 本文主要内容如下: 1.MVC基本介绍 2.MVC在表视图中的应用 3.总结 MVC基本介绍 MVC模式这个名词太熟悉,不过本人由于缺乏工程实践经验,对其理解目前还停留在理论的表面层次上.在iOS开发中MVC模式第一次在表视图设计中应用到,想借此机会对其有个初步的认识.MVC在表视图中的对号入座,目前的理解为如下图所示

iOS开发初探篇——UINavigationBar及UINavigationController

概述 导航在iOS开发中的重要性就不多说了.通常UINavigationController会结合UITabBar一起使用,此初探篇是单独对UINavigationBar及UINavigationController做一个比较全面的基础使用. 本文主要内容如下: 1.UINavigationBar的基础使用 2.UINavigationController的基础使用 3.设计Label中其他的相关类 UINavigationBar的基础使用 UINavigationBar一般位于屏幕的顶端.继承

iOS开发初探篇——Label的使用

概述 本文介绍Label的一些常规用法.由于满足UI需求时会存在很多细节的问题,所以需要对Label能做到一个比较灵活的使用.首先感谢博主KC写的精彩博文. 本文主要内容如下: 1.Labe的一些基本方法和属性 2.Label控件如何自动适应控件中text的大小 3.设计Label中其他的相关类 Labe的一些基本方法和属性 至于基本方法和属性,看如下示例: UILabel *label = [[UILabel alloc]init]; label.backgroundColor = [UICo

iOS - Rac(ReactiveCocoa)

一.储备 Block使用场景 二.编程思想 前沿:面对需求,往往需要可以快速实现需求,在一过程,就是编程思想. 2.1 面向过程 2.2 面向对象 2.3 链式编程思想 2.4 响应式编程思想 2.5 函数时编程思想 原文地址:https://www.cnblogs.com/share-iOS/p/8215802.html

爱上iOS单元测试系列之爱上她就要先了解她:单元测试入门

前言 对于单元测试一开始我是拒绝的.单元测试是一个什么东东,因为我喜欢做iOS开发是因为喜欢写APP的啊,一切和这一目标不相干的东西我没兴趣啊,所以从事iOS开发几年都没去深入学习过单元测试(主要是之前单位没这要求).看到我的优点木有:目标性很强,嗯,记住我的优点,请忽略我拒绝学习边缘知识的缺点.但是最近被总监要求负责单元测试的探索和落地,我义(勉)不(为)容(其)辞(难)地扛起了夺取桥头堡的重任.随着对这个姑娘的不断的了解和接触,我发现自己逐渐爱上了她,她有着独立知性的气质,有着完美丰满的身材

iOS单元測试:Specta + Expecta + OCMock + OHHTTPStubs + KIF

框架选择 參考这篇选型文章,http://zixun.github.io/blog/2015/04/11/iosdan-yuan-ce-shi-xi-lie-dan-yuan-ce-shi-kuang-jia-xuan-xing/,尽管结论不一定全然适用,可是关于框架对照的地方还是值得阅读的.基于这篇文章,排除Kiwi框架之后,决定參考一些项目的源码,了解他们使用的測试方面的框架. 首先,參考https://github.com/artsy/eigen开源项目,其内部总体结构很完整,开发流程也很

[HMLY]7.iOS MVVM+RAC 从框架到实战

1.MVVM浅析 MVC是构建iOS App的标准模式,是苹果推荐的一个用来组织代码的权威范式,市面上大部分App都是这样构建的,具体组织模式不细说,iOS入门者都比较了解(虽然不一定能完全去遵守),但其几个不能避免的问题却是很严重困扰开发者,比如厚重的ViewControlller.遗失的网络逻辑(没有属于它的位置).较差的可测试性等.因此也就会有维护性很强.耦合性很低的一种新架构MVVM(MVC引申出的最新架构)的流行. MVVM虽然来自微软,但是不应该反对它,它正式规范了视图和控制器紧耦合