Reactive Cocoa中的超时实现是否正确?

时间:2015-02-07 17:34:26

标签: ios cocoa reactive-cocoa

我做了一个登录,它连接到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
        }];

1 个答案:

答案 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];

here is a blog article talking about RACCommands