I am using the CoreLocation's geocoder to get the CLLocation coordinates for multiple map items. The geocoder calls a completion block on completion for each item.
How do I create a similar block functionality which is called when all of these containing asynchronous geocoder calls have been completed? (I could use a manual counter. But there must be a more elegant solution)
Here's my geocoding function so far. It loops through an array of location items and starts a new geocoding process for each.
-(void)geoCodeAllItems {
for (EventItem* thisEvent in [[EventItemStore sharedStore] allItems]) {
if (![thisEvent eventLocationCLLocation]){ //Only geocode if the item has no location data yet
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
[geocoder geocodeAddressString:[thisEvent eventLocationGeoQuery] completionHandler:^(NSArray *placemarks, NSError *error) {
if (error){
NSLog(@"\t Geo Code - Error - Failed to geocode";
return;
}
if (placemarks)
{
if ([placemarks count] > 1) NSLog(@"\t Geo Code - Warning - Multiple Placemarks (%i) returned - Picking the first one",[placemarks count]);
CLPlacemark* placemark = [[CLPlacemark alloc]initWithPlacemark:[placemarks objectAtIndex:0]];
CLLocationCoordinate2D placeCoord = [[placemark location]coordinate];
[thisEvent setEventLocationCLLocation:[[CLLocation alloc]initWithLatitude:placeCoord.latitude longitude:placeCoord.longitude]];
[[EventItemStore sharedStore] saveItems];
} else {
NSLog(@"\t Geo Code - Error - No Placemarks decoded");
}
}];
geocoder = nil;
}
}
}
This basically works however due to the asynchronous fashion I don't know when all geocoding activity has finally ended.
My feeling is, I either have to create an block for this or use Grand Central Dispatch but I am not really sure. I appreciate any help on this to find the right approach.