HTML5技术

iOS开发之ReactiveCocoa下的MVVM(干货分享) - 青玉伏案(4)

字号+ 作者:H5之家 来源:H5之家 2015-11-11 09:25 我要评论( )

文字说完了,如果有些小伙伴还不太明白,那看下面这张原理图吧。把三种信号量我们可以类比成十字路口的红绿灯。successObject就是绿灯,可以走正常流程。failureObject是黄灯,先等一下,完成该做的就可以走绿灯了

    文字说完了,如果有些小伙伴还不太明白,那看下面这张原理图吧。把三种信号量我们可以类比成十字路口的红绿灯。successObject就是绿灯,可以走正常流程。failureObject是黄灯,先等一下,完成该做的就可以走绿灯了。而errorObject就是一红灯,报错异常,终止业务流程并提升错误信息。有图有真相,到这儿如果还不理解我就没招了。

    在Public方法中- (id) buttonIsValid; 负责返回登录按钮是否可用的信号量。- (void)login;发起网络请求,调用登录网络接口。

  

    (2)代码的具体实现如下(VCViewModel.m中的代码),私有属性如下。userNameSignal用来存储用户名的信号量,passwordSignal是用来存储密码的信号量。reqestData则是用来存储返回数据的。

1 @interface VCViewModel () 2 @property (nonatomic, strong) RACSignal *userNameSignal; 3 @property (nonatomic, strong) RACSignal *passwordSignal; 4 @property (nonatomic, strong) NSArray *requestData; 5 @end

 

    (3)VCViewModel的初始化方法如下,负责初始化属性。

1 - (instancetype)init 2 { 3 self = [super init]; 4 if (self) { 5 [self initialize]; 6 } 7 return self; 8 } 9 10 - (void)initialize { 11 _userNameSignal = RACObserve(self, userName); 12 _passwordSignal = RACObserve(self, password); 13 _successObject = [RACSubject subject]; 14 _failureObject = [RACSubject subject]; 15 _errorObject = [RACSubject subject]; 16 }

  

    (4) 发送登录按钮是否可用信号的方法如下,主要用到了信号量的合并。

//合并两个输入框信号,并返回按钮bool类型的值 - (id) buttonIsValid { RACSignal *isValid = [RACSignal combineLatest:@[_userNameSignal, _passwordSignal] reduce:^id(NSString *userName, NSString *password){ return @(userName.length >= 3 && password.length >= 3); }]; return isValid; }

 

    (5) 模拟网络请求的发送,并发出网络请求成功的信号,具体代码如下

1 - (void)login{ _requestData = @[_userName, _password]; [_successObject sendNext:_requestData]; }

 

  4. 上面是VM的实现,如果要进行单元测试的话,就对相应的VM类进行初始化,调用相应的函数进行单元测试即可。接着就是看如何在相应的VC模块中使用VM。

    (1) 在VC中实例化相应的VM类,并绑定相应的参数和实现接收不同信号的方法,具体代码如下:

- (void)bindModel { 3 _viewModel = [[VCViewModel alloc] init]; RAC(self.viewModel, userName) = self.userNameTextField.rac_textSignal; 7 RAC(self.viewModel, password) = self.passwordTextField.rac_textSignal; 8 RAC(self.loginButton, enabled) = [_viewModel buttonIsValid]; 9 10 @weakify(self); [self.viewModel.successObject subscribeNext:^(NSArray * x) { 14 @strongify(self); bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:]; 16 vc.userName = x[0]; 17 vc.password = x[1]; 18 [self presentViewController:vc animated:YES completion:^{ 19 20 }]; 21 }]; [self.viewModel.failureObject subscribeNext:^(id x) { 25 26 }]; [self.viewModel.errorObject subscribeNext:^(id x) { 30 31 }]; 32 33 }

 

    (2) 点击登录按钮,调用VM中登录相应的网络请求方法即可

1 - (void)onClick { [[self.loginButton rac_signalForControlEvents:UIControlEventTouchUpInside] 4 subscribeNext:^(id x) { 5 [_viewModel login]; 6 }]; 7 }

 

    到此为止,一个完整模拟登录模块的RAC下的MVVM就实现完毕。当然上面的Demo是非常简陋的,还有好多地方需要进化。不过麻雀虽小,道理你懂得。主要是通过上面的Demo来感受一下RAC中的信号量机制以及应用场景。

 

    5.上面代码写完,我们就可以运行看一下运行效果了,下方是运行后的效果,

  

 

  上述工程GitHub分享链接:https://github.com/lizelu/MVVMWithReactiveCocoa

  其他参考资料:

        https://github.com/ReactiveCocoa/ReactiveViewModel

        http://www.teehanlax.com/blog/model-view-viewmodel-for-ios/

        http://www.teehanlax.com/blog/getting-started-with-reactivecocoa/

        http://nshipster.cn/reactivecocoa/

        http://limboy.me/ios/2013/06/19/frp-reactivecocoa.html

        https://vimeo.com/65637501

        http://southpeak.github.io/blog/2014/08/08/mvvmzhi-nan-yi-:flickrsou-suo-shi-li/

        http://southpeak.github.io/blog/2014/08/02/reactivecocoazhi-nan-%5B%3F%5D-:xin-hao/

        http://southpeak.github.io/blog/2014/08/02/reactivecocoazhi-nan-er-:twittersou-suo-shi-li/

 

 

 

        ViewModel:

          Kicking off network or database requests

          Determining when information should be hidden or shown

          Date and number formatting

          Localization

 

        ViewController:

          Layout

          Animations

          Device rotation 

          View and window transitions

          Presenting loaded UI

 

 

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • CSS gradient渐变之webkit核心浏览器下的使用以及实例 - 孟然

    CSS gradient渐变之webkit核心浏览器下的使用以及实例 - 孟然

    2017-02-04 15:00

  • 移动web开发之rem响应式设计 - 放羊的星星bky

    移动web开发之rem响应式设计 - 放羊的星星bky

    2016-10-25 10:03

  • 关于IOS中safari下的select下拉菜单,文字过长不换行的问题 - 梦影雾花,尽是虚空

    关于IOS中safari下的select下拉菜单,文字过长不换行的问题 - 梦影雾

    2016-09-27 17:00

  • 如何独立开发一个网络请求框架 - 指尖下的幽灵

    如何独立开发一个网络请求框架 - 指尖下的幽灵

    2016-08-15 11:00

网友点评
=