NLU NLU - 5 months ago 11
Objective-C Question

make 3 "for" loops wait for async answer. obj-c ios

I'm working on an app for iPad iOS 8, and I need to make my app wait for an answer from:

[directions calculateETAWithCompletionHandler:^(MKETAResponse *response, NSError *error) {}]


This method is inside 3 loops. I tried
dispatch_semaphore_t
, but the app can't continue after this line:

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);


and gets stuck. I tried with
dispatch_group_t
and got the same result.
I guess that I'm doing something wrong, but I don't know what. I tried to search SO for similar problems and but found nothing. Can someone explain how I could accomplish this?

-(void)setTimesMissions {

for (Driver *d in self.dataList) {

for (Period *p in d.periods) {

for (Mission *m in p.missions) {

MKDirections *directions = ....

// HERE i want the for loop stop until this completionHandler finish
[directions calculateETAWithCompletionHandler:^(MKETAResponse *response, NSError *error) {

//and when he finish here continue
}];
}
}
}


}

Answer

Call your method in dispatch_async block.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [youClassInstance setTimesMissions];
});

And use dispatch_semaphore_wait in your loop

- (void)setTimesMissions {
    Mission *home = [[Mission alloc]init];
    Mission *next = [[Mission alloc]init];
    for (Driver *d in self.dataList) {

        home.clientLat = d.centralPointLat;
        home.clientLon = d.centralPointLon;
        home.clientPaddres = d.centralAddress;

        for (Period *p in d.periods) {

            home.times = [[NSMutableArray alloc]init];

            if ([p.periodIx isEqualToString:self.thisPeriodIX]) {

                for (Mission *m in p.missions) {

                    Mission *source = home;
                    Mission *destination = m ;
                    MKPlacemark *placemarkSource = [[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake([source.clientLat doubleValue], [source.clientLon doubleValue]) addressDictionary:nil] ;
                    MKMapItem *mapItemSource = [[MKMapItem alloc] initWithPlacemark:placemarkSource];

                    MKPlacemark *placemarkDestination = [[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake([destination.clientLat doubleValue], [destination.clientLon doubleValue])addressDictionary:nil] ;
                    MKMapItem *mapItemDestination = [[MKMapItem alloc] initWithPlacemark:placemarkDestination];

                    MKDirectionsRequest *directionsRequest = [[MKDirectionsRequest alloc] init];
                    [directionsRequest setSource:mapItemSource];
                    [directionsRequest setDestination:mapItemDestination];
                    directionsRequest.transportType = MKDirectionsTransportTypeAutomobile;
                    [directionsRequest setRequestsAlternateRoutes:NO];
                    MKDirections *directions = [[MKDirections alloc] initWithRequest:directionsRequest];

                    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
                    __block double timeTo;

                    [directions calculateETAWithCompletionHandler:^(MKETAResponse *response, NSError *error) {

                        if ( response.expectedTravelTime) {
                            timeTo = response.expectedTravelTime;
                            double ans = timeTo;
                            Time *t = [[Time alloc]init];
                            t.ix = m.serviceIX;
                            t.time = ans;
                            [home.times addObject:t];
                        }

                        dispatch_semaphore_signal(semaphore);
                    }];

                    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
                }

                 dispatch_async(dispatch_get_main_queue(), ^{
                      // code that should be executed on main queue 
                 });


                if (next.clientPaddres) {
                    home = next;
                }
            }
        }        
    }
}
Comments