CLGeocoder fails silently

Aug 8, 2012 · Follow on Twitter and Mastodon objcgeo

I’m currently developing a location-based app for iPad and iPhone, that will allow users to store locations and use custom icons and colors for the pins.

This is how it currently looks:

App Screenshot

In the app, you can pin your location, pin any place by pressing the map or search for an address, which uses CLGeocoder to find a coordinate for an address.

Searching for addresses hasn’t been working great, though. If I search for a street in my current city, I get results in other towns, like Nykoping and Uppsala.

For clarity, this is the exact method body I use to kick off a search operation:

CLLocationCoordinate2D *coord = self.mapView.userLocation.location.coordinate;
CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:coord
radius:10000
identifier:nil];

id<ForwardGeocoder> geocoder = [ObjectFactory getForwardGeocoder];
geocoder.delegate = self;
[geocoder encodeAddressString:self.searchBar.text inRegion:region];

I first accepted the bad search results as a limitation in CLGeocoder’s geocoding abilities for Swedish addresses, but then noticed that the same problem occurred for American addresses as well.

As I couldn’t get things to work with CLGeocoder, I decided to return to the Google-based geocoder I used before - Björn Sållarp’s BSGeocoder. I tried CLGeocoder, since BSForwardGeocoder didn’t support viewport biasing. As it now does, I decided to give it another try.

In the app, I use an abstract protocol to define how geocoding is done in the app. This makes it really easy to switch out implementations. As I replaced Björn’s approach with CLGeocoder, I changed the protocol to use CLRegion instead of MKCoordinateRegion.

When I re-added Björn’s code, I changed my wrapper class (that implements the protocol and serves as a bridge between the app and the geocoding implementation) so it used a CLRegion as well. As I did, I faced the same behavior using Bjorn’s implementation.

So, Björn’s geocoder used to work, and now didn’t. Considering that, I realized that the only difference between the old and new implementations (except that the library was updated a bit by Björn) was that I now used CLRegion class instead of MKCoordinateRegion.

I therefore decided to inspect the resulting CLRegion value in the code above, and now noticed that the center lat/long was zero!

How could this be? I verified that the user location was not zero, so how could the resulting CLRegion have a zero center? Reading the documentation, I found the answer:

The identifier must not be nil!

So, all this was due to the fact that I used a nil identifier, but the app never gave me so much as a silent warning about this. If I pass in nil as an identifier, which I did:

  • I don’t get a nil CLRegion in return, but a region with a nil center.
  • I don’t crash the application.
  • I don’t get any errors whatsoever.

Instead, I end up with a valid CLRegion, but with invalid properties. Talk about crashing silently.

Discussions & More

Please share any ideas, feedback or comments you may have in the Disqus section below, or by replying on Twitter or Mastodon..

If you found this text interesting, make sure to follow me on Twitter and Mastodon for more content like this, and to be notified when new content is published.

If you like & want to support my work, please consider sponsoring me on GitHub Sponsors.