1

我正在尝试将我的 iOS 应用程序重构为 ReactiveCocoa 和 ReactiveViewModel 并且我正在努力尝试制定几个最佳实践。

我将把它归结为一个简单的用例——我要推送一个视图控制器,它会加载一些数据并将其推送到表格视图中。如果端点调用由于某种原因失败,我想在屏幕上显示一个带有重试按钮的视图。

我目前有这个工作,但它看起来有点脏。我觉得必须有更好的方法——我这样做是否正确?

在我的 ViewModel 的init方法中,我正在创建我的命令,一旦 ViewModel 变为活动状态就会调用该命令。

// create the command to load the data
@weakify(self);
self.loadStationsCommand = [[RACCommand alloc] initWithSignalBlock:^(RACSignal *(id input) {
    @strongify(self);
    return [RACSignal createSignal:^(RACDisposable *(id<RACSubscriber subscriber) {
        // load data from my API endpoint
        ...
        BOOL succeeded = ...;
        if (succeeded) {
            [subscriber sendNext:nil];
            [subscriber sendCompleted:nil];
        } else {
            // failed
            [subscriber sendError:nil];   
        }
        return nil;
    }
}];

// start the command when the ViewModel's ready
[self.didBecomeActiveSignal subscribeNext:^(id x) {
    @strongify(self);
    [self.loadStationsCommand execute:nil];
}];

在我的 UIViewController 中,我通过 -

[self.viewModel.loadStationsCommand.executionSignals subscribeNext:^(RACSignal *loadStationsSignal) {
    [loadStationsSignal subscribeNext:^(id x) {
        // great, we got the data, reload the table view. 
        @strongify(self);
        [self.tableView reloadData];
    } error:^(NSError *error) {
        // THIS NEVER GETS CALLED?!
    }];
}];

[self.viewModel.loadStationsCommand.errors subscribeNext:^(id x) {
    // I actually get my error here. 
    // Show view/popup to retry the endpoint.
    // I can do this via [self.viewModel.loadStationsCommand execute:nil]; which seems a bit dirty too.
}];

我一定对它的RACCommand工作原理有一些误解,或者至少我觉得我没有尽我所能干净地做到这一点。

为什么我的错误块没有loadStationsSignal被调用?为什么我需要订阅executionCommand.errors呢?

有没有更好的办法?

4

1 回答 1

2

这是处理错误的正确方法RACCommand。正如您在文档中看到的那样,使用时不会发送内部信号的错误 executionSignals

 Errors will be automatically caught upon the inner signals, and sent upon
 `errors` instead. If you _want_ to receive inner errors, use -execute: or
 -[RACSignal materialize].

您还可以使用 RAC对按钮的添加UIButton和绑定。self.viewModel.loadStationsCommandrac_commandretry

有一篇很好的文章解释了 RACCommand并展示了一些与之一起使用的有趣模式。

于 2015-04-15T09:22:01.943 回答