How to find out when a for loop with NSURLSessionDataTasks is completed

I call a method that will list through an array, create an NSURL and call NSURLSessionDataTask, which returns JSON. The cycle usually runs about 10 times, but can vary depending on the day.

I need to wait for the for loop and all NSURLSessionDataTasks before I can start processing the data.

It's hard for me to figure out when all the work is completed. Can anyone recommend any methods or logic to know when the whole method is complete (for loop and data tasks)?

-(void)findStationsByRoute{
for (NSString *stopID in self.allRoutes) {
    NSString *urlString =[NSString stringWithFormat:@"http://truetime.csta.com/developer/api/v1/stopsbyroute?route=%@", stopID];
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request
                                                 completionHandler:^(NSData *data,
                                                                     NSURLResponse *response,
                                                                     NSError *error) {
                                                     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                                                     if(httpResponse.statusCode == 200){
                                                         NSError *jsonError = [[NSError alloc]init];
                                                         NSDictionary *stopLocationDictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
                                                         NSArray *stopDirectionArray = [stopLocationDictionary objectForKey:@"direction"];
                                                         for (NSDictionary * _stopDictionary in stopDirectionArray) {
                                                             NSArray *stop =   [_stopDictionary objectForKey:@"stop"];
                                                             [self.arrayOfStops addObject:stop];

                                                         }
                                                     }

                                                 }];

    [task resume];
}

}

+4
source share
2 answers

. , , - .

:

  • . dispatch_group_enter, dispatch_group_leave , , dispatch_group_notify, , "enter" "":

    - (void)findStationsByRoute {
        dispatch_group_t group = dispatch_group_create();
    
        for (NSString *stopID in self.allRoutes) {
            NSString     *urlString = [NSString stringWithFormat:@"http://truetime.csta.com/developer/api/v1/stopsbyroute?route=%@", stopID];
            NSURL        *url       = [NSURL URLWithString:urlString];
            NSURLRequest *request   = [NSURLRequest requestWithURL:url];
    
            dispatch_group_enter(group);   // enter group before making request
    
            NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                if(httpResponse.statusCode == 200){
                    NSError *jsonError;   // Note, do not initialize this with [[NSError alloc]init];
                    NSDictionary *stopLocationDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
                    NSArray *stopDirectionArray = [stopLocationDictionary objectForKey:@"direction"];
                    for (NSDictionary *stopDictionary in stopDirectionArray) {
                        NSArray *stop = [stopDictionary objectForKey:@"stop"];
                        [self.arrayOfStops addObject:stop];
                    }
                }
    
                dispatch_group_leave(group);  // leave group from within the completion handler
            }];
    
            [task resume];
        }
    
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            // do something when they're all done
        });
    }
    
  • - NSSessionDataTask NSOperation, . , "" (.. isFinished ). , maxConcurrentOperationCount, , . 3-4 .

    , , . , NSOperation.

    . " " Operation Queue Concurrency.

    NSURLSessionTask NSOperation . NSURLSession NSBlockOperation . , NSOperation .

  • /, [NSURLSessionConfiguration backgroundSessionConfiguration] URLSessionDidFinishEventsForBackgroundURLSession: NSURLSessionDelegate, , , . ( , , , : , , , , .)

    ( ), / . 10 ( ), .

  • , , , , , .

+5

, :

 create group
 for (url in urls)
     enter group
     start_async_task
         when complete leave group

 wait on group to finish or supply a block to be run when completed
+3

All Articles