ReactiveCocoa使用记录-网络登录事件

对于一个应用来说,绝大部分的时间都是在等待某些事件的发生或响应某些状态的变化,比如用户的触摸事件、应用进入后台、网络请求成功刷新界面等等,而维护这些状态的变化,常常会使代码变得非常复杂,难以扩展。而 ReactiveCocoa 给出了一种非常好的解决方案,它使用信号来代表这些异步事件,提供了一种统一的方式来处理所有异步的行为,包括代理方法、block 回调、target-action 机制、通知、KVO 等:

// 代理方法
[[self
    rac_signalForSelector:@selector(webViewDidStartLoad:)
    fromProtocol:@protocol(UIWebViewDelegate)]
    subscribeNext:^(id x) {
        // 实现 webViewDidStartLoad: 代理方法
    }];

// target-action
[[self.avatarButton
    rac_signalForControlEvents:UIControlEventTouchUpInside]
    subscribeNext:^(UIButton *avatarButton) {
        // avatarButton 被点击了
    }];

// 通知
[[[NSNotificationCenter defaultCenter]
    rac_addObserverForName:kReachabilityChangedNotification object:nil]
    subscribeNext:^(NSNotification *notification) {
        // 收到 kReachabilityChangedNotification 通知
    }];

// KVO
[RACObserve(self, username) subscribeNext:^(NSString *username) {
    // 用户名发生了变化
}];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

1.监听UITextField数值 赋值ViewModel

RAC(self.loginVM, username) = _textFieldAccount.rac_textSignal;
  • 1

2.监听ViewModel数值 赋值UILabel

RAC(self.labelRoundNumber, text) = RACObserve(self.homePageVM, waitNum);
  • 1

问题:RAC 和RACOberve的区别?RAC(tagartA,keypathA)是对对象tagartA的keypathA属性进行赋值,RACObserve(tagartB,keypathB)是监听tagartB的keypathB属性的值;

3.监听UITextView控件 text属性

@weakify(self);
[self.textViewAdvice.rac_textSignal subscribeNext:^(NSString *content){
    @strongify(self);
    self.textFieldPlaceholder.hidden = (content && content.length > 0);
}];
  • 1
  • 2
  • 3
  • 4
  • 5

4.监听UIButton控件 UIControlEventTouchUpInside事件

@weakify(self)
[[self.buttonLogin
  rac_signalForControlEvents:UIControlEventTouchUpInside]
 subscribeNext:^(id x) {
     @strongify(self)
         [MBProgressHUD showHUDAddedTo:self.view
                              animated:NO];
         [self.loginVM sendLogin];
 }];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5.自定义RACSubject消息

@property (nonatomic, strong, readwrite) RACSubject *successLogin;
@property (nonatomic, strong, readwrite) RACSubject *failureLogin;

- (void)initialize {
    _successLogin = [RACSubject subject];
    _failureLogin = [RACSubject subject];
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

6.消息RACSubject传递

- (void)sendLogin {
    NSDictionary *dictParams = @{
                                 @"UserName":self.username,
                                 @"PassWord":self.password
                                 };
    @weakify(self);
    [WebServiceManager requestLoginWithParams:dictParams
                                     andBlock: ^(id data, id error) {
                                         @strongify(self);
                                         if (error) {
                                             return;
                                         }
                                         if ([data isMemberOfClass:[UserModel class]]) {
                                             [self.successLogin sendNext:userModel];
                                         }
                                         else {
                                             [self.failureLogin sendNext:(NSString *)data];
                                         }
                                     }];
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

7.消息RACSubject接收

@weakify(self)
[self.loginVM.successLogin subscribeNext:^(UserModel *userModel) {
    @strongify(self);
    [UserModel userModel:userModel];
    [HomePageVC rootViewController];
    [MBProgressHUD hideHUDForView:self.view
                         animated:YES];
}];

[self.loginVM.failureLogin subscribeNext:^(NSString *data) {
    @strongify(self);
    self.textFieldAccount.text = @"";
    self.textFieldPassword.text = @"";
    kMRCError(data);
    [MBProgressHUD hideHUDForView:self.view
                         animated:YES];
}];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

8.监听键盘通知

[[[NSNotificationCenter defaultCenter]
  rac_addObserverForName:UIKeyboardWillShowNotification
  object:nil]
 subscribeNext:^(NSNotification *notification) {
     NSDictionary *info = [notification userInfo];
     NSValue *keyboardFrameValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
     CGRect keyboardFrame = [keyboardFrameValue CGRectValue];
     CGFloat height_temp = 195 - (kViewHeight(self.view) - keyboardFrame.size.height - 90) / 2;
     [_scrollViewMaster setContentOffset:CGPointMake(0, height_temp)
                                animated:YES];
 }
 ];

[[[NSNotificationCenter defaultCenter]
  rac_addObserverForName:UIKeyboardWillHideNotification
  object:nil]
 subscribeNext:^(NSNotification *notification) {
     [_scrollViewMaster setContentOffset:CGPointMake(0, 0)
                                animated:YES];
 }
 ];

[[NSNotificationCenter defaultCenter] removeObserver:self
                                                name:UIKeyboardWillShowNotification
                                              object:nil];

[[NSNotificationCenter defaultCenter] removeObserver:self
                                                name:UIKeyboardWillHideNotification
                                              object:nil];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

MVVM+RAC

MVVM在功能上其实是Model+View(view、ViewController)+ViewModel,所以与之前不同的地方就是每个ViewController都会有一个与之对应的ViewModel,它处理业务逻辑和网络请求,从而降低ViewController的臃肿。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DevanChen/article/details/50993663
原文地址:https://www.cnblogs.com/feng9exe/p/8665770.html