Im relatively a new iOS developer, and im dealing with the geocoder completion handler, i do not understand how to update a variable with the address find by the geocoder and the do some stuff with it. In few words, i want that the geocoder block finishes to use the info in some method.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(@"didUpdateToLocation: %@", newLocation);
CLLocation *currentLocation = newLocation;
if (currentLocation != nil) {
longitudeLabel = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
latitudeLabel = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
}
[locationManager stopUpdatingLocation];
// Reverse Geocoding
NSLog(@"Resolving the Address");
__block NSString * **annotation**;
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
if (error == nil && [placemarks count] > 0) {
placemark = [placemarks lastObject];
NSLog(@"location %@",addressLabel);*/
**annotation**=[NSString stringWithFormat:@" %@, %@, %@",
placemark.locality,
placemark.administrativeArea,
placemark.country];
}
} ];
NSLog(@"location %@",annotation);
NSString *text = self.toPostCell.postText.text;
UIImage *image = self.toPostCell.selectedImage.image;
[Persistence addPostToServerAddtext:text addimage:image addbeach:nil **location:annotation**];
[NSThread sleepForTimeInterval:5.0];
self.posts = [Persistence getPostsUpTo: self.cantPosts forBeach:nil];
imageLoaded = NO;
[self.tableView reloadData];
}
I have tried the dispatch main queue, and i cant get the annotation and use it in the method, after a deep search around the web im a bit confused about threads, queues and the order of there execution. When running the method it throws the exception EXC_BAD_ACCESS when logging the annotation after the block....
The reverseGeocodeLocation
method runs asynchronously, so you shouldn't reference the annotation
outside of the completionHandler
block. The annotation
string has not been set by the point you get to that code after the reverseGeocodeLocation
block.
Thus, you might want to move your code after the reverseGeocodeLocation
block to inside it, resolving this asynchronous issue:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(@"didUpdateToLocation: %@", newLocation);
CLLocation *currentLocation = newLocation;
if (currentLocation != nil) {
longitudeLabel = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
latitudeLabel = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
}
[locationManager stopUpdatingLocation];
// Reverse Geocoding
NSLog(@"Resolving the Address");
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
if (error == nil && [placemarks count] > 0) {
placemark = [placemarks lastObject];
NSLog(@"location %@",addressLabel);*/
NSString *annotation = [NSString stringWithFormat:@" %@, %@, %@",
placemark.locality,
placemark.administrativeArea,
placemark.country];
NSLog(@"location %@",annotation);
NSString *text = self.toPostCell.postText.text;
UIImage *image = self.toPostCell.selectedImage.image;
[Persistence addPostToServerAddtext:text addimage:image addbeach:nil location:annotation];
// I'm not sure why you're sleeping 5 seconds, but if you really want to do
// something five seconds later you should probably `dispatch_after`, thus
// instead of:
//
// [NSThread sleepForTimeInterval:5.0];
//
// you might want to do the following:
double delayInSeconds = 5.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
self.posts = [Persistence getPostsUpTo: self.cantPosts forBeach:nil];
imageLoaded = NO;
[self.tableView reloadData];
});
}
} ];
}