When using CLLocationManager directly, you normally get a cached location in the first callback. It's normally a good location, although old. After that you quickly get additional callbacks giving better locations using wifi, cell tower (if available). If you have asked for < 1000m accuracy you will (after more seconds) get GPS triangulation.
None of those should be inaccurate enough to be in the middle of the ocean. I suspect that the this line of code:
self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate;
is accessing the coordinate while userLocation
or location
is nil
. If userLocation
or location
is nil, this will return 0 coordinates. The location of lat=0, lon=0 is in the Atlantic Ocean, off the coast of Africa. You could add a check of location
to make sure it is not nil before getting the coordinate from it, ie:
if (self.mapView.userLocation.location) {
self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate;
[mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES];
}
You will also want to wait for callbacks to the MKMapViewDelegate mapView:didUpdateUserLocation:
to know when there is a valid location available. Your implementation of didUpdateUserLocation:
should discard any location that has a horizontalAccuracy < 0 which indicates an invalid location.
-(void)mapView:(MKMapView*)mapView didUpdateUserLocation:(MKUserLocation*)userLocation
{
if (userLocation.location.horizontalAccuracy > 0) {
[mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES];
}
}