iPhone Development – Reverse Geocoding

A rather nifty new feature of the iPhone SDK is the ability to reverse geocode a location. Some of you may be wondering what normal geocoding is! Well, geocoding is turning an address into a latitude and longitude. So reverse geocoding is, without surprise, turning a latitude and longitude into an address.

So, in combination with the normal iPhone lookup services, you can find out the lat,long of someone and then convert that into a friendly place name such as the town they are in. It’s very easy to do, firstly you need to implement the MKReverseGeocoderDelegate protocol in your chosen class which has two callbacks, one for when a reverse geocode is successful and one for when there is an error:

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder  didFindPlacemark:(MKPlacemark *)placemark;
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error;

So we create and initialise a reverse Geocoder with the following code. Note the delegate is set to self so the methods defined above should be places in the same class. locationToLookup defines where the location name we want to look up is (as a latitude, longitude coordinate).

        // use whatever lat / long values or CLLocationCoordinate2D you like here.
        CLLocationCoordinate2D locationToLookup = {52.0,0};
        MKReverseGeocoder *reverseGeocoder = [[MKReverseGeocoder alloc] initWithCoordinate:locationToLookup];
        reverseGeocoder.delegate = self;
        [reverseGeocoder start];

The first time I tried this I got the very cryptic error message below:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[LBSGAddressComponent _mapkit_cache_heapTime]: unrecognized selector sent to instance 0x166c00'

After a lot of head scratching I realised this is because you must only ever have one reverse geocoder running at once. So I made the reverse geocoder a class variable (to keep track of it) and added:

        if (reverseGeocoder != nil)
        {
            // release the existing reverse geocoder to stop it running
            [reverseGeocoder release];
        }

        // use whatever lat / long values or CLLocationCoordinate2D you like here.
        CLLocationCoordinate2D locationToLookup = {52.0,0};
        MKReverseGeocoder *reverseGeocoder = [[MKReverseGeocoder alloc] initWithCoordinate:locationToLookup];
        reverseGeocoder.delegate = self;
        [reverseGeocoder start];

This will stop any existing lookups. And so if successful your callback method will be called with an instance of MKPlacemark that represents where your lookup is. Easy.

2 Responses to “iPhone Development – Reverse Geocoding”

  1. [...] Go here to read the rest: iPhone Development – Reverse Geocoding « evilrockhopper.com [...]

  2. [...] This post was mentioned on Twitter by iPhone Dev News, Daniel Wichett. Daniel Wichett said: Reverse geocoding on the iPhone http://evilrockhopper.com/2010/01/iphone-development-reverse-geocoding/ [...]

Leave a Reply