ios - Reactive Cocoa 和短时间内的多个 AFNetworking 请求

标签 ios afnetworking afnetworking-2 reactive-cocoa

我正在努力解决使用 AFNetworking 和 Reactive Cocoa 处理对 Web 服务的多个请求的方式。在这种情况下,用户要求 API 为字符/整数搜索输入提供一堆建议,以从列表中选择一个城市。

这是我的代码:

首先是当用户输入超过 3 个字符/整数时立即执行的方法

- (void)fetchData:(NSString *)searchText
{
    NSLog(@"%@", searchText);

    if ([searchText validateStringwithPattern:BKPostcodeRegEx]) {
        self.searchURL = [NSString stringWithFormat:@"%@location/postalCode/%@/%@", BKBaseURL, self.countryCode, searchText];
    } else if ([searchText validateStringwithPattern:BKCityRegEx]) {
        self.searchURL = [NSString stringWithFormat:@"%@location/city/%@/%@", BKBaseURL, self.countryCode, searchText];
    } else {
        NSLog(@"Error Alert - No Valid Input");
        return;
    }

    RAC(self, searchResults) = [[[self postRequest] map:^(NSDictionary *json) {
        NSArray *results = json[@"data"][@"locations"];
        return results;
    }] catch:^(NSError *error) {
        return [RACSignal return:@[]];
    }];
}

现在这是我实际创建信号并将其传递回 self.searchResults 的地方:

- (RACSignal *)postRequest
{
    return [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [self.requestOperationManager GET:self.searchURL parameters:self.params success:^(AFHTTPRequestOperation *operation, id responseObject) {
            [subscriber sendNext:responseObject];
            [subscriber sendCompleted];
        }failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            [subscriber sendError:error];
        }];

        return [RACDisposable disposableWithBlock:^{
            [self.requestOperationManager.operationQueue cancelAllOperations];
        }];

    }] doError:^(NSError *error) {
        NSLog(@"error: %@", [error description]);
    }] throttle:0.5];
}

我认为问题是,我在当前信号完成之前的信号之前开始订阅信号,因此在我尝试再次订阅时导致异常。

* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Signal name: [[[[+createSignal:] -doError:] -throttle: 0.500000] -map:] -catch: is already bound to key path "searchResults" on object , adding signal name: [[[[+createSignal:] -doError:] -throttle: 0.500000] -map:] -catch: is undefined behavior'

我的猜测是我必须在 postRequest 方法中尝试这样的事情,但这似乎不是开箱即用的:

if (self.requestOperationManager.operationQueue.operationCount == 1) {
  NSLog(@"cancel all operations");
  [self.requestOperationManager.operationQueue cancelAllOperations];
  [subscriber sendCompleted];
}

最佳答案

您只能在任何给定对象的键路径上调用一次 RAC()。看起来 -fetchData: 可以被多次调用,这将导致 RAC() 在同一对象和关键路径上被多次调用。

通常,您在某种设置方法(例如初始化程序或-[UIViewController loadView])中调用RAC(),这样它只会被调用一次。不要等到用户键入超过 3 个字符然后调用 -fetchData:,而是考虑如何创建一个信号,当用户键入超过 3 个字符时发送一个值,并分配该信号到 RAC() 的属性。例如(完全未经测试):

- (void)someInitializationMethod
{
    RACSignal *moreThan3 = [[myTextField rac_textSignal] filter:^(NSString *text) {
        return [text length] > 2;
    }];

    RAC(self, searchResults) = [self rac_liftSelector:@selector(fetchData:) withSignals:moreThan3];
}

- (void)fetchData:(NSString *)searchText
{
    if ([searchText validateStringwithPattern:BKPostcodeRegEx]) {
        // ... etc ...
    }

    return [[[self postRequest] map:^(NSDictionary *json) {
        NSArray *results = json[@"data"][@"locations"];
        return results;
    }] catch:^(NSError *error) {
        return [RACSignal return:@[]];
    }];
}

- (RACSignal *)postRequest
{
    // ... etc ...

关于ios - Reactive Cocoa 和短时间内的多个 AFNetworking 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23059512/

相关文章:

ios - MVC - View 可以保留对其 View Controller 的引用并处理数据吗?

ios - 如何在沙盒模式下知道自动更新产品更新

objective-c - AFNetworking pod install 使用未解析的标识符方法

ios - AFNetworking GET 请求 - 无法将responseObject转换为NSDictionary

iOS:对 Alamofire 与 AFNetworking 的质疑

ios - 仅从 Assets 集合类型 PHAssetCollectionTypeSmartAlbum 中获取类型为 PHAssetMediaTypeImage 的照片

java - JBoss 上的 IOS 身份验证和 Java 应用

ios - AFNetworkActivirty 记录器 swift 3.0 xcode 8 不记录任何内容

ios - 如何清除图像缓存或 AFNetworking 中的任何缓存?

ios - AFNetworking 版本 2 内容类型错误