// // RQVerificationSmsCodeViewModel.m // YueXueChe // // Created by 张嵘 on 2018/12/14. // Copyright © 2018 lee. All rights reserved. // #import "RQVerificationSmsCodeViewModel.h" #import "YYTimer.h" @interface RQVerificationSmsCodeViewModel () /// closeCommand @property (nonatomic, readwrite, strong) RACCommand *closeCommand; /// registerCommand @property (nonatomic, readwrite, strong) RACCommand *sureCommand; /// 验证码命令 @property (nonatomic, readwrite, strong) RACCommand *captchaCommand; /// 注册按钮有效性 @property (nonatomic, readwrite, strong) RACSignal *validSureSignal; /// 验证码按钮能否点击 @property (nonatomic, readwrite, strong) RACSignal *validCaptchaSignal; /// 验证码显示 @property (nonatomic, readwrite, copy) NSString *captchaTitle; /// error (PS;这个记录请求过程中的发生的错误,请求之前必须置nil) @property (nonatomic, readwrite, strong) NSError *error; /// Timer @property (nonatomic, readwrite, strong) YYTimer *timer; /// Count @property (nonatomic, readwrite, assign) NSUInteger count; /// valid (有效性) @property (nonatomic, readwrite, assign) BOOL valid; /// phone @property (nonatomic, readwrite, copy) NSString *phone; /// captcha @property (nonatomic, readwrite, copy) NSString *captcha; @end @implementation RQVerificationSmsCodeViewModel - (instancetype)initWithServices:(id)services params:(NSDictionary *)params { if (self = [super initWithServices:services params:params]) { self.phone = params[RQMobileLoginPhoneKey]; } return self; } - (void)initialize { [super initialize]; /// 显示导航栏的细线 self.prefersNavigationBarBottomLineHidden = NO; self.title = @"修改密码"; @weakify(self); self.closeCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { @strongify(self); [self.services dismissViewModelAnimated:YES completion:NULL]; return [RACSignal empty]; }]; /// 按钮的有效性 self.validSureSignal = [[RACSignal combineLatest:@[RACObserve(self, phone),RACObserve(self, captcha)] reduce:^(NSString *phone , NSString *captcha) { return @(RQStringIsNotEmpty(phone) && RQStringIsNotEmpty(captcha)); }] distinctUntilChanged]; /// 验证码按钮有效性 self.captchaTitle = @" 获取验证码 "; RAC(self, valid) = [[RACObserve(self, timer.valid) map:^id(NSNumber * value) { return @(!value.boolValue); }] distinctUntilChanged]; /// 验证码有效性 self.validCaptchaSignal = RACObserve(self, valid); self.captchaCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { @strongify(self); /// 将错误置为nil self.error = nil; self.valid = NO; self.captchaTitle = @" 发送中... "; return [self getSmsCode]; }]; self.sureCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(NSDictionary *captchadic) { @strongify(self); self.error = nil; // 先置nil self.captcha = captchadic[RQCaptchaKey]; return [self verificationSmsCode]; }]; } #pragma mark - Action - (void)_timerValueChanged:(YYTimer *)timer { self.count--; if (self.count == 0) { [timer invalidate]; self.timer = nil; [self _resetCaptcha]; return; } self.captchaTitle = [NSString stringWithFormat:@" %zds后重新发送 ", self.count]; } #pragma mark - 辅助方法 - (void)_resetCaptcha { self.valid = YES; self.captchaTitle = @" 获取验证码 "; } - (RACSignal *)getSmsCode { /// 执行 @weakify(self); return [[[RACSignal createSignal:^RACDisposable *(id subscriber) { [[RQ_HTTP_Service getCodeWithTelePhone:self.phone] subscribeNext:^(id _Nullable x) { [subscriber sendNext:x]; } error:^(NSError * _Nullable error) { [subscriber sendError:error]; } completed:^{ [subscriber sendCompleted]; }]; return [RACDisposable disposableWithBlock:^{ /// 取消任务 }]; }] doNext:^(id x) { @strongify(self); self.count = RQCaptchaFetchMaxWords; self.captchaTitle = @" 60s后重新发送 "; self.timer = [YYTimer timerWithTimeInterval:1 target:self selector:@selector(_timerValueChanged:) repeats:YES]; }] doError:^(NSError *error) { @strongify(self); self.error = error; self.valid = YES; self.captchaTitle = @" 发送验证码 "; }]; } - (RACSignal *)verificationSmsCode { @weakify(self); return [[[RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) { [[RQ_HTTP_Service verificationSmsCodeWithMobile:self.phone type:RQSMSCodeFindPassword code:self.captcha] subscribeNext:^(id _Nullable x) { [subscriber sendNext:x]; } error:^(NSError * _Nullable error) { [subscriber sendError:error]; } completed:^{ [subscriber sendCompleted]; }]; return [RACDisposable disposableWithBlock:^{ /// 取消任务 }]; }] doNext:^(id _Nullable x) { RQUpdatePasswordViewModel *model = [[RQUpdatePasswordViewModel alloc] initWithServices:self.services params:nil]; [self.services pushViewModel:model animated:YES]; }] doError:^(NSError * _Nonnull error) { @strongify(self); self.error = error; }] ; } @end