我做了一个登录,它连接到ReactiveCocoa中的一个按钮。即使我测试了这段代码,它似乎工作正常,我不确定我是否正确。 登录信号在成功时返回“next”,在任何其他情况下返回“error”。由于我不希望在错误上取消订阅Button,因此我使用catch函数。
我想要的:如果没有触发loginSignal,我希望在2秒后触发超时。这是正确的吗?是否也采用了“反应方式”?
[[[[self.loginButton rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(id x) {
[self disableUI];
}]
flattenMap:^(id value) {
return [[[[[self.login loginSignalWithUsername:self.usernameTextField.text
andPassword:self.passwordTextField.text]
catch:^RACSignal *(NSError *error) {
[self enableUI];
[self showAlertWithTitle:NSLocalizedString(@"ERROR_TITLE", @"Error")
message:NSLocalizedString(@"LOGIN_FAILURE", @"Login not successful.")];
return [RACSignal empty];
}]
deliverOn:[RACScheduler mainThreadScheduler]]
timeout:2.0 onScheduler:[RACScheduler mainThreadScheduler]]
catch:^RACSignal *(NSError *error) {
[self enableUI];
[self showAlertWithTitle:NSLocalizedString(@"TIMEOUT_TITLE", @"Timeout occured")
message:NSLocalizedString(@"REQUEST_NOT_POSSIBLE", @"Server request failed")];
return [RACSignal empty];
}];
}]
subscribeNext:^(id x) {
[self enableUI];
// Go to next page after login
}];
答案 0 :(得分:2)
在我看来,您应该使用RACCommand,这是一个很好的集线器,用于将信号绑定到UI:
RACCommand* command = [[RACCommand alloc] initWithSignalBlock:^(id _) {
return [[[self.login loginSignalWithUsername:self.username password:self.password]
doCompleted:^{
// move to next screen
}]
timeout:2.0 onScheduler:[RACScheduler mainThreadScheduler]];
}];
self.button.rac_command = command;
然后,您可以使用命令" errors"处理任何错误(登录或超时)。信号:
[[command errors] subscribeNext:^(NSError* err) {
// display error "err" to the user
}];
信号将在执行时自动禁用按钮。如果您需要禁用UI的其他部分,可以使用"执行"命令的信号。
[[command executing] subscribeNext:^(NSNumber* executing) {
if([executing boolValue]) {
[self disableUI];
} else {
[self enableUI];
}
}];
// bonus note: if your enableUI method took a BOOL you could lift it in one line :
[self rac_liftSelector:@selector(enableUI:) withSignals:[command executing], nil];