如何在 ReactiveCocoa 中使用 sendError
How to use sendError in ReactiveCocoa
我是反应式 Cocoa 的新手,到目前为止非常喜欢它。
我创建了一个注册页面。如果用户名和密码有效,我启用注册按钮。对于登录按钮,我做了以下操作:
[[[[self.registerButton rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(id x) {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
self.registerButton.enabled = NO;
}]
flattenMap:^RACStream *(id value) {
Login *login = [Login new];
return [login registerSignalWithName:self.usernameTextField.text
andPassword:self.passwordTextField.text];
}]
subscribeNext:^(NSDictionary *result) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
// Go to next page
}
error:^(NSError *error) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:error.localizedDescription
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}];
我的问题:如果用户名已经存在我 return 一个错误。但是如果我 return 出错,那么 registerButton 上 rac_signalForControlEvents 的订阅将结束!我不会再收到任何信号,我的 registerButton 也不会再有反应。根据文档,这是正确的行为。
另一方面:如果我在出现错误时使用 sendNext 而不是 sendError,我在 sendNext 上有不同的 return 类型(错误或成功时带有结果的字典)。那也不好。所以错误在这种情况下不可用,因为它不允许简单的错误处理。
该问题的正确反应解决方案是什么?
您可以使用 catch:
来达到这个目的。
[[[[self.registerButton rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(id x) {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
self.registerButton.enabled = NO;
}]
flattenMap:^RACStream *(id value) {
Login *login = [Login new];
return [[login registerSignalWithName:self.usernameTextField.text
andPassword:self.passwordTextField.text]
catch:^RACSignal *(NSError *error) {
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle:@"Error"
message:error.localizedDescription
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
return [RACSignal empty];
}];
}]
subscribeNext:^(NSDictionary *result) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
error:^(NSError *error) {}];
catch:
的工作方式与 flattenMap:
类似,但 catch:
对 error 事件做出反应,而不是 next 事件。
我是反应式 Cocoa 的新手,到目前为止非常喜欢它。
我创建了一个注册页面。如果用户名和密码有效,我启用注册按钮。对于登录按钮,我做了以下操作:
[[[[self.registerButton rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(id x) {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
self.registerButton.enabled = NO;
}]
flattenMap:^RACStream *(id value) {
Login *login = [Login new];
return [login registerSignalWithName:self.usernameTextField.text
andPassword:self.passwordTextField.text];
}]
subscribeNext:^(NSDictionary *result) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
// Go to next page
}
error:^(NSError *error) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:error.localizedDescription
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}];
我的问题:如果用户名已经存在我 return 一个错误。但是如果我 return 出错,那么 registerButton 上 rac_signalForControlEvents 的订阅将结束!我不会再收到任何信号,我的 registerButton 也不会再有反应。根据文档,这是正确的行为。
另一方面:如果我在出现错误时使用 sendNext 而不是 sendError,我在 sendNext 上有不同的 return 类型(错误或成功时带有结果的字典)。那也不好。所以错误在这种情况下不可用,因为它不允许简单的错误处理。
该问题的正确反应解决方案是什么?
您可以使用 catch:
来达到这个目的。
[[[[self.registerButton rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(id x) {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
self.registerButton.enabled = NO;
}]
flattenMap:^RACStream *(id value) {
Login *login = [Login new];
return [[login registerSignalWithName:self.usernameTextField.text
andPassword:self.passwordTextField.text]
catch:^RACSignal *(NSError *error) {
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle:@"Error"
message:error.localizedDescription
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
return [RACSignal empty];
}];
}]
subscribeNext:^(NSDictionary *result) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
error:^(NSError *error) {}];
catch:
的工作方式与 flattenMap:
类似,但 catch:
对 error 事件做出反应,而不是 next 事件。