简体   繁体   中英

NSURLConnection send request after finish all process

I have a nested loop of sending the request.

-(void) download
{
   for(NSString *id in array)
   {
    //init with request and start the connection
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request deletegate:self];
    [conn start];
   }
}

-(void) connection:(NSURLConnection *) connection didReceiveData:(NSData *) data
{
//enter here secondly
}
-(void) connectionDidFinishLoading:(NSURLConnection *) connection
{
//enter here last, after finish the for loop
//my intention is use the downloaded data to do something before sending a new request.
}

The problem is that I want to enter "-(void) connectionDidFinishLoading:(NSURLConnection *) connection" first before send the request again in the for loop.

But currently it will finish the for loop and sent all the request before enter to "-(void) connectionDidFinishLoading:(NSURLConnection *) connection" .

You Should Try This NSURLConnection is deprecated in iOS9

for (NSString *URL in URLArray) {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];

NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    // check error and/or handle response here 
}];
[task resume];
}

and use dispatch_group_t group = dispatch_group_create();

add line to for loop dispatch_group_enter(group); will call

dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    // Request Finish
});

for your goal

In your case you need to try block function because as per your requirement you want response of the first connection for another request.

for(NSString* url in array)
{
   // Generate a NSURLRequest object from the address of the API.
   NSURL *url = [NSURL URLWithString:urlLink];
   NSURLRequest *request = [NSURLRequest requestWithURL:url];

   // Send the request asynchronous request using block!
   [NSURLConnection sendAsynchronousRequest:request
                                      queue:[NSOperationQueue mainQueue]
                          completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

                           if (error) {
                               NSLog(@"Error in updateInfoFromServer: %@ %@", error, [error localizedDescription]);
                           } else if (!response) {
                               NSLog(@"Could not reach server!");
                           } else if (!data) {
                               NSLog(@"Server did not return any data!");
                           } else {
                               [self doStuffWithData:data];
                           }
                       }];
}

URL loading is not a synchronous operation (or at least should never be done synchronously), because it can take up to 90 seconds just for a DNS lookup failure, and almost infinitely long if the server keeps dribbling out data. If you block the main thread for even a fraction of that amount of time, iOS will kill your app.

Instead of scheduling the requests in a loop and waiting for them to finish, you need to schedule the first request (and only the first request). Then, in your connectionDidFinishLoading: method (and maybe your connection:DidFailWithError: method), schedule the next request.

With that said, unless you still need to support iOS 6/10.8 and earlier, you should probably be using NSURLSession. (The same general advice applies; the delegate method names are changed to protect the guilty.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM