按下按钮后,从rac_GET创建RACSignal,取消之前的请求

时间:2014-04-08 08:53:56

标签: cocoa reactive-cocoa

在完成本教程之后,我正在尝试在Reactive Cocoa中进行第一次练习。目标是使用AFNetworking和这些ReactiveCocoa wrappers按钮从互联网上下载一些内容。

我想出了这个:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer.acceptableContentTypes = nil;
RACSignal *buttonSignal = [self.stepperButton rac_signalForControlEvents:UIControlEventTouchUpInside];
RACSignal *getSignal = [buttonSignal map:^id(UIButton *button) {
    return [manager rac_GET:@"https://farm3.staticflickr.com/2815/13668440264_e6403b3100_o_d.jpg" parameters:nil];
}];
RACSignal *latestSignal = [getSignal switchToLatest];
[latestSignal subscribeNext:^(id x) {
    NSLog(@"x: %@",x);
}];

这似乎做了我想要的几件事:

  1. 根据要求从flickr下载图像
  2. 当点击按钮太快时取消上一个请求(此处为switchToLatest键)
  3. 但它在其他方面失败了:

    1. 我的subscribeNext似乎无法获得有效的回复。 x始终为null
    2. 每当请求失败时,信号就会进入错误状态,按下该按钮不会再触发任何新的GET。
    3. 我想我在这里遗漏了很多东西,因为我是Reactive Cocoa的新手,但也许有人愿意提示让我朝着正确的方向前进?

      还有其他方法我看不到吗?

1 个答案:

答案 0 :(得分:1)

这似乎有效:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = nil;
RACSignal *buttonSignal = [self.stepperButton rac_signalForControlEvents:UIControlEventTouchUpInside];
RACSignal *getSignal = [buttonSignal map:^id(UIButton *button) {
    return [[manager rac_GET:@"https://farm3.staticflickr.com/2815/13668440264_e6403b3100_o_d.jpg" parameters:nil] catch:^RACSignal *(NSError *error) {
        NSLog(@"catch %@",error);
        return [RACSignal empty];
    }];
}];
RACSignal *latestSignal = [getSignal switchToLatest];
[latestSignal subscribeNext:^(NSData *data) {
    NSLog(@"dowloaded %d bytes",data.length);
}];

感谢Stackoverflow类似的问题!强大的东西。

捕获应该在rac_GET上。在我尝试用buttonSignal管道进行捕获之前。

x始终null的原因是因为我没有在manager上设置序列化程序。

我考虑过删除这个问题,但也许还有人对解决方案有评论意见?