连续启动NSURLConnection请求

时间:2014-09-17 08:03:35

标签: ios nsurlconnection

我循环遍历包含少量字符串的数组,并为每个字符串向Web服务器发出请求 数组中的字符串。

我希望在将后续请求发送到服务器之前完全处理每个请求。因为每个请求都会向我发送一个响应,我将在下一个请求时发送,等等。

我遇到的问题是我的NSURLConnection是使用标准异步调用设置的。这导致请求不阻止任何后续请求。但是我需要在第一次完成之前阻止循环中的其他请求。

请求URL始终相同,只有JSON数据随循环中的每个请求而变化。 这是我的代码

for (int i = 0; i < array.count; i++)
{


     NSData *jsonData = [NSJSONSerialization dataWithJSONObject:finalJSON options:NSJSONWritingPrettyPrinted error:&error];
     if (!jsonData) {
                NSLog(@"Error creating JSON object: %@", [error localizedDescription]);
            }


      NSString *url = [NSString stringWithFormat:@“abc.com/folders”];

      NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];

      [request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"];
      [request setValue:APIKEY forHTTPHeaderField:@"X_API_KEY"];

      [request setHTTPMethod:@"POST"];
      [request setHTTPBody:jsonData];

            //I am adding all connections to NSDictionary so that later I can process request.
      NSURLConnection *connection = [self connectionForRequest:request];
      [connection start];                

}

2 个答案:

答案 0 :(得分:1)

我想到了解决问题的两种解决方案:

  1. AFNetworking - 你可以使用AFNetworking并在成功块中维护一个计数器。计数器将对请求进行计数,完成所有操作后,将执行下一个任务。

  2. GCD - Dispatch Groups - Grand Central Dispatch为您提供制作小组或请求的选项,并在最后(当所有请求完成时)执行某些操作。为此,你需要阅读精彩的教程(“Ray Wenderlich”的第2部分。如果你不熟悉GCD,请跳到教程的第1部分)。

  3. 无论如何,上面的代码U无法完成你的任务。你没有在请求结束时运行的任何异步块。

    修改

    使用AFNetworking:

    你必须首先删除你的for循环,然后这样做:

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    NSDictionary *parameters = @{@"foo": @"bar"};
    [manager POST:@"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { // HERE u can do your second request which uses the first response
    
            AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
            NSDictionary *parameters_new = <USE_YOUR_DATA_FROM_responseObject>;
            [manager POST:@"http://example.com/resources.json" parameters:parameters      success:^(AFHTTPRequestOperation *operation, id responseObject) { // HERE u can do your third request which uses the first and second response
    
    
    
            } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                 NSLog(@"Error: %@", error);
            }]; 
    
    
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
    

答案 1 :(得分:0)

一种简单的方法是使用递归。创建一个发送url连接的方法,并在连接完成后调用自身再次发送它。

这是解决方案的关键:制作一个可以递归调用的方法,该方法可以发送请求并收集结果。通过在完成块中递归调用自身,此方法可以确保每个请求在上一个请求完成后开始...

// note - edited per the comments to get a new NSURLRequest each time
- (void)makeRequests:(NSInteger)count
             results:(NSMutableArray *)results
          completion:(void (^)(NSError *))completion {

    // complete recursion
    if (count == 0) return completion(nil);

    NSURLRequest *request = [self nextRequest];

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

        if (!error) {
            [results addObject:data];
            [self makeRequests:count-1 results:results completion:completion];
        } else {
            completion(error);
        }
    }];
}

要调用它,请分配一个包含结果的数组......

- (void)makeManyRequests {

    NSMutableArray *resultsArray = [NSMutableArray array];
    [self makeRequests:10 results:resultsArray completion:^(NSError *error) {
        NSLog(@"done.  results are %@", resultsArray);
    }];
}

编辑 - 它在OP中不清楚这个请求每次都会如何变化,但听起来你已经弄明白了。这只是您最初在自己的方法中发布的代码。这是一个好主意,因此您的代码可以清楚地了解每次它如何形成不同的JSON有效负载......

- (NSURLRequest *)nextRequest {

    id finalJSON = // your app supplies...
    // somehow, this changes each time nextRequest is called

    NSString *APIKEY = // your app supplies
    NSError *error;

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:finalJSON options:NSJSONWritingPrettyPrinted error:&error];
    if (!jsonData) {
        NSLog(@"Error creating JSON object: %@", [error localizedDescription]);
    }

    // your request creation code, copied from the OP
    NSString *url = [NSString stringWithFormat:@"abc.com/folders"];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];

    [request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [request setValue:APIKEY forHTTPHeaderField:@"X_API_KEY"];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:jsonData];
    return request;
}