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:
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
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
CLGeocoder, I changed the protocol to use
CLRegion instead of
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
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
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
CLRegion have a zero center? Reading the documentation, I found
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.