ios - 将 RACCommand 组合成一个共同结果的最佳方法是什么?

标签 ios objective-c reactive-cocoa

使用 ReactiveCocoa 2.0,是否有更好的方法来执行以下操作,而无需具体化/取消具体化,并且仍然能够从 3 个信号中的任何一个捕获错误,而无需重复代码?

有 3 个登录按钮。每个都返回一个对应于异步“登录”API 调用的信号。一旦完成,它们将返回用户对象、错误和/或完成。

// Login signals
_loginButton.rac_command = [[RACCommand alloc] initWithEnabled:loginValid signalBlock:^RACSignal *(id input) {
    return [[API doLogin:_usernameField.text password:_passwordField.text] materialize];
}];
_fbLoginButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    return [[API doFacebookLogin] materialize];
}];
_twLoginButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    return [[API doTwitterLogin] materialize];
}];

// Login response from any of the 3 signals
[[RACSignal
  merge:@[_loginButton.rac_command.executionSignals,
          _fbLoginButton.rac_command.executionSignals,
          _twLoginButton.rac_command.executionSignals]]
 subscribeNext:^(RACSignal *loginSignal) {
     RACSignal * s = [loginSignal dematerialize];
     [s subscribeNext:^(User *x) {
        NSLog(@"user: %@", x);
     } error:^(NSError *error) {
        NSLog(@"error: %@", error);
     } completed:^{
        NSLog(@"Completed.");
     }];
 }];

最佳答案

由于错误会自动转移到 errors 信号,您通常不必自己处理具体化或任何其他事情。事实上,这种(潜在的)复杂性是错误的特殊行为的最初动机。

只需合并错误信号并在一个地方处理它们:

[[RACSignal
    merge:@[
        _loginButton.rac_command.errors,
        _fbLoginButton.rac_command.errors,
        _twLoginButton.rac_command.errors,
    ]]
    subscribeNext:^(NSError *error) {
        NSLog(@"error: %@", error);
    }];

作为旁注,您还可以使用 -flatten(而不是内部订阅)来简化登录响应的处理:

[[[RACSignal
    merge:@[
        _loginButton.rac_command.executionSignals,
        _fbLoginButton.rac_command.executionSignals,
        _twLoginButton.rac_command.executionSignals,
    ]]
    // Flattens the signal of `User` signals by one level. The result is
    // one signal of `User`s.
    //
    // This avoids any need for an inner subscription.
    flatten]
    subscribeNext:^(User *x) {
        // This means that a login request completed as well, so there's no need
        // for a separate `completed` block.
        NSLog(@"user: %@", x);
    }];

关于ios - 将 RACCommand 组合成一个共同结果的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19867331/

相关文章:

ios - 如何通过xcode中的向导在sqlite中创建数据库以及如何连接数据库?

iOS下载批量图像的最佳方式

iphone - TableView不显示数据?

iphone - FBWebDialog 在 iOS 7 中出现时消失

ios - swift 1.2 上的 RACCommand 编译失败

ios - 如何仅针对特定屏幕尺寸缩小字体

ios - UITextField - 返回时向下滚动

iphone - 删除以某个单词开头的所有 NSUserDefaults

ios - 使用 ReactiveCocoa 跟踪远程对象的 UI 更新

swift - 响应式(Reactive) cocoa 尝试图返回类型