Domanda

I am new to ObjC and I am struggling with the CLGeocoder. I want to be able to use reverseGeocodeLocation to obtain a string that contains the user location that I pass to my delegate when the user presses a Done button.

So the user triggers the display of a MapViewController, I call the reverseGeocodeLocation in the viewDidLoad but the [placemarks count = 0] this first time in, and I have no placemark to get the info that I need. The second time the user triggers the display of the MapViewController the placemarks array has been populated and everything works.

I suspect it is something to do with the reverseGeocodeLocation being an asynchronous call - but I cannot figure out how to solve this problem. I have tried searching online but nothing seems to help me understand what I am doing wrong and how i can solve this issue. Thanks in advance.

@interface MapViewController ()
@property (strong, nonatomic) CLGeocoder *geocoder;
@property (readwrite, nonatomic) NSString *theLocationName;
@end

@implementation MapViewController
@synthesize mapView, geocoder, delegate = _delegate, theLocationName = _theLocationName;

- (void)viewDidLoad
{
[super viewDidLoad];

self.mapView.delegate=self;
self.mapView.showsUserLocation = YES;

[self theUserLocation];
}

-(void)theUserLocation
{
if (!geocoder)
{
    geocoder = [[CLGeocoder alloc] init];
}

MKUserLocation *theLocation;
theLocation = [self.mapView userLocation];

[geocoder reverseGeocodeLocation:theLocation.location 
               completionHandler:^(NSArray* placemarks, NSError* error)
 {
     if ([placemarks count] > 0)
     {
         CLPlacemark *placemark = [placemarks objectAtIndex:0];

         [self setTheLocationName: placemark.locality];

     }
 }];

- (IBAction)done:(id)sender 
{

[[self delegate] mapViewControllerDidFinish:self locationName:[self theLocationName]];

}

@end
È stato utile?

Soluzione

So the user triggers the display of a MapViewController, I call the reverseGeocodeLocation in the viewDidLoad but the [placemarks count = 0] this first time in, and I have no placemark to get the info that I need. The second time the user triggers the display of the MapViewController the placemarks array has been populated and everything works.

It's not because the call is asynchronous - it's because the first time you call theUserLocation the actual location isn't available. Getting the user's location is not instantaneous - it takes time. However, you're asking for the user's location as soon as the map loads, which in most circumstances won't work.

What you need to do is hook into the MKMapViewDelegate methods, which provide you with callbacks when the location is updated. You can use this to check the location's accuracy, and decide whether it is accurate enough for you to reverse geolocate.

Altri suggerimenti

This is not exact answer to your question but, if you can switch to other solution apart from CLGeocoder than following function can help you to get address from given latitude, longitude

#define kGeoCodingString @"http://maps.google.com/maps/geo?q=%f,%f&output=csv" //define this at top

-(NSString *)getAddressFromLatLon:(double)pdblLatitude withLongitude:(double)pdblLongitude
{
    NSString *urlString = [NSString stringWithFormat:kGeoCodingString,pdblLatitude, pdblLongitude];
    NSError* error;
    NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error];
    locationString = [locationString stringByReplacingOccurrencesOfString:@"\"" withString:@""];
    return [locationString substringFromIndex:6];
}

Credit : Selected Answer to this question

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top