iOS RAC - 登錄頁面忘晤,MVVM

文章系列
《RACSignal 》
《RACDisposable》
《RACSubject窃判、RACReplaySubject》
《iOS RAC - 基本用法》
《iOS RAC - 定時器》
《iOS RAC - RACMulticastConnection》
《iOS RAC - RACCommand》
《iOS RAC - 核心方法bind》
《iOS RAC - 集合RACTuple燥爷、RACSequence》
《iOS RAC - rac_leftSelector》
《iOS RAC - 映射》
《iOS RAC - 過濾》
《iOS RAC - 登錄頁面,MVVM》



git地址



先布局UI

在storyboard中拖入兩個textField和一個button,在ViewController中引用谅辣,并且在storyboard中設(shè)置按鈕默認(rèn)不可以點(diǎn)擊修赞。


1、對用戶名和密碼做限制(用戶名長度不能少于1位桑阶,密碼必須是六位數(shù)及以上)
   ///監(jiān)聽文本框輸入狀態(tài)柏副,確定按鈕是否可以點(diǎn)擊
    RAC(_loginBtn,enabled) = [RACSignal combineLatest:@[_accountTF.rac_textSignal,_passwordTF.rac_textSignal] reduce:^id _Nullable(NSString * account,NSString * password){
        return @(account.length && (password.length > 5));
    }];


2、監(jiān)聽按鈕點(diǎn)擊狀態(tài)
    [[_loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"點(diǎn)擊了  點(diǎn)擊了");
    }];


3蚣录、把按鈕的點(diǎn)擊事件割择,包裝成為一個command

在command中我們會模擬網(wǎng)絡(luò)請求,監(jiān)聽登錄成功的信號萎河,同時去監(jiān)聽command的執(zhí)行過程

    RACCommand * btnPressCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        
        NSLog(@"組合參數(shù)荔泳,準(zhǔn)備發(fā)送登錄請求");
        
        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            NSLog(@"開始請求");
            
            NSLog(@"請求成功");
            
            NSLog(@"處理數(shù)據(jù)");
            
            [subscriber sendNext:@"請求完成,數(shù)據(jù)給你"];
            
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"結(jié)束了");
            }];
        }];
    }];
    
    [btnPressCommand.executionSignals.switchToLatest subscribeNext:^(id  _Nullable x) {
        NSLog(@"登錄成功虐杯,跳轉(zhuǎn)頁面");
    }];
    
    [[btnPressCommand.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
        if ([x boolValue]) {
            NSLog(@"正在執(zhí)行中……");
        }else{
            NSLog(@"執(zhí)行結(jié)束了");
        }
    }];

4玛歌、準(zhǔn)備工作都完成啦,現(xiàn)在在按鈕點(diǎn)擊的時候就執(zhí)行command

    [[_loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"點(diǎn)擊了  點(diǎn)擊了");
        
        [btnPressCommand execute:@{@"account":_accountTF.text,@"password":_passwordTF.text}];
        
    }];
2017-10-28 11:04:07.912743+0800 RAC[467:49597] 點(diǎn)擊了  點(diǎn)擊了
2017-10-28 11:04:07.913775+0800 RAC[467:49597] 組合參數(shù)擎椰,準(zhǔn)備發(fā)送登錄請求 - {
    account = jack;
    password = 123456;
}
2017-10-28 11:04:07.918380+0800 RAC[467:49597] 正在執(zhí)行中……
2017-10-28 11:04:07.919022+0800 RAC[467:49597] 開始請求
2017-10-28 11:04:07.919115+0800 RAC[467:49597] 請求成功
2017-10-28 11:04:07.919196+0800 RAC[467:49597] 處理數(shù)據(jù)
2017-10-28 11:04:07.919688+0800 RAC[467:49597] 登錄成功支子,跳轉(zhuǎn)頁面

這里沒有執(zhí)行完成,原因是因為在commnad中返回的信號达舒,沒有調(diào)用sendCompleted

2017-10-28 11:06:21.270969+0800 RAC[471:50127] 結(jié)束了
2017-10-28 11:06:21.271169+0800 RAC[471:50127] 執(zhí)行結(jié)束了




MVVM

在剛才的代碼中我們實現(xiàn)了功能值朋,但是全部都寫在了VC中叹侄,這樣子顯然是不夠好的,所以我們一般都會采取MVC對VC進(jìn)行瘦身吞歼,在RAC中更多的時候是使用MVVM圈膏。
所以接下來就使用MVVM來把VC瘦身吧

1塔猾、創(chuàng)建VM
創(chuàng)建一個VMLoginViewModel篙骡,導(dǎo)入到VC中,并且懶加載他

@property (nonatomic, strong) LoginViewModel *loginVM;


@implementation ViewController

- (LoginViewModel *)loginVM{
    if (!_loginVM){
        _loginVM = [[LoginViewModel alloc] init];
    }
    return _loginVM;
}



2丈甸、開始抽離

  • 2.1抽離文本框邏輯(這個部分VC并不關(guān)心糯俗,所以需要抽離出來)
    文本框有兩個,一個是用戶名睦擂,一個是密碼得湘,兩個文本框的值我們需要知道并保存,所以需要添加兩個屬性account顿仇、password淘正、
@property (nonatomic, strong) NSString *account;
@property (nonatomic, strong) NSString *password;

然后在VC中賦值

    RAC(self.loginVM,account) = _accountTF.rac_textSignal;
    RAC(self.loginVM,password) = _passwordTF.rac_textSignal;

現(xiàn)在拿到了值,那么我要把結(jié)果告訴給VC臼闻,所以我們還需要創(chuàng)建一個Signal

@property (nonatomic, strong) RACSignal *btnEnableSignal;

信號肯定要初始化對吧

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self setUp];
    }
    return self;
}

- (void)setUp{
    //RACObserve可以把KVO轉(zhuǎn)化為信號
    _btnEnableSignal =  [RACSignal combineLatest:@[RACObserve(self,account),RACObserve(self, password)] reduce:^id _Nullable(NSString * account,NSString * password){
        return @(account.length && (password.length > 5));
    }];
}

現(xiàn)在只需要在VC中訂閱我們這個信號就好了

    RAC(_loginBtn,enabled) = self.loginVM.btnEnableSignal;



2.2 抽離command(VC也不關(guān)心你怎么處理數(shù)據(jù)鸿吆,怎么去請求,VC只需要知道結(jié)果就夠了)
創(chuàng)建一個command

@property (nonatomic, strong) RACCommand *loginCommand;

然后就是把剛才寫好的代碼賦值到VM的setUp方法當(dāng)中

- (void)setUp{
    //RACObserve可以把KVO轉(zhuǎn)化為信號
    _btnEnableSignal =  [RACSignal combineLatest:@[RACObserve(self,account),RACObserve(self, password)] reduce:^id _Nullable(NSString * account,NSString * password){
        return @(account.length && (password.length > 5));
    }];
    
    _loginCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        
        NSLog(@"組合參數(shù)述呐,準(zhǔn)備發(fā)送登錄請求 - %@",input);
        
        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            NSLog(@"開始請求");
            
            NSLog(@"請求成功");
            
            NSLog(@"處理數(shù)據(jù)");
            
            [subscriber sendNext:@"請求完成惩淳,數(shù)據(jù)給你"];
            
            [subscriber sendCompleted];
            
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"結(jié)束了");
            }];
        }];
    }];
    

    
    [[_loginCommand.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
        if ([x boolValue]) {
            NSLog(@"正在執(zhí)行中……");
        }else{
            NSLog(@"執(zhí)行結(jié)束了");
        }
    }];
}

最后把按鈕按下的時候執(zhí)行的command改成為VM里面的command就可以了。

    [[_loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"點(diǎn)擊了  點(diǎn)擊了");
        [self.loginVM.loginCommand execute:@{@"account":_accountTF.text,@"password":_passwordTF.text}];
    }];

最終使用MVVM之后呢乓搬,在VC的代碼就是這樣子的

- (void)viewDidLoad {
    [super viewDidLoad];
    
    RAC(self.loginVM,account) = _accountTF.rac_textSignal;
    RAC(self.loginVM,password) = _passwordTF.rac_textSignal;
    
    RAC(_loginBtn,enabled) = self.loginVM.btnEnableSignal;
    
    [self.loginVM.loginCommand.executionSignals.switchToLatest subscribeNext:^(id  _Nullable x) {
        NSLog(@"登錄成功思犁,跳轉(zhuǎn)頁面");
    }];
    
    [[_loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"點(diǎn)擊了  點(diǎn)擊了");
        [self.loginVM.loginCommand execute:@{@"account":_accountTF.text,@"password":_passwordTF.text}];
    }];
}



相比較于之前什么都在VC中處理,確實給VC瘦身不少

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末进肯,一起剝皮案震驚了整個濱河市激蹲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌江掩,老刑警劉巖学辱,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異频敛,居然都是意外死亡项郊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門斟赚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來着降,“玉大人,你說我怎么就攤上這事拗军∪味矗” “怎么了蓄喇?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長交掏。 經(jīng)常有香客問我妆偏,道長,這世上最難降的妖魔是什么盅弛? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任钱骂,我火速辦了婚禮,結(jié)果婚禮上挪鹏,老公的妹妹穿的比我還像新娘见秽。我一直安慰自己,他們只是感情好讨盒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布解取。 她就那樣靜靜地躺著,像睡著了一般返顺。 火紅的嫁衣襯著肌膚如雪禀苦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天遂鹊,我揣著相機(jī)與錄音振乏,去河邊找鬼。 笑死稿辙,一個胖子當(dāng)著我的面吹牛昆码,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播邻储,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼赋咽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吨娜?” 一聲冷哼從身側(cè)響起脓匿,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宦赠,沒想到半個月后陪毡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡勾扭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年毡琉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妙色。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡桅滋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情丐谋,我是刑警寧澤芍碧,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站号俐,受9級特大地震影響泌豆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吏饿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一踪危、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧找岖,春花似錦陨倡、人聲如沸敛滋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绎晃。三九已至蜜唾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間庶艾,已是汗流浹背袁余。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留咱揍,地道東北人颖榜。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像煤裙,于是被迫代替她去往敵國和親掩完。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載:http://ios.jobbole.com/83602/ 最近工作比較忙硼砰,但還是出來更新博客了且蓬,今天給大家...
    VV木公子閱讀 4,076評論 3 28
  • 前言 看了下上篇博客的發(fā)表時間到這篇博客,竟然過了11個月血公,罪過昵仅,罪過。這一年時間也是夠折騰的坞笙,年初離職跳槽到鵝廠...
    西木柚子閱讀 21,236評論 12 184
  • 誰曾品嘗我的苦澀 聽我憂愁岩饼,知我心惑 不快樂的人也厭惡痛苦 誰又能愛上悲劇角色荚虚? 你把真實的我留給我自己 我守著雕...
    夜谷閱讀 280評論 0 5
  • C語言: include<sdio.h> printf("Matrix7y"); OC語言: import<Fou...
    深藍(lán)碎片_閱讀 133評論 0 0
  • 上一秒讀著吳曉波的文字,下一秒就打開了大司馬的直播間籍茧。這兩位在出身背景版述,學(xué)識見地上毫無相似之處的人,在17年...
    dc7f23f818a9閱讀 455評論 0 0