Question

I recently started testing my app on an iPhone 5, and to my alarm, it seems that the CLLocationManager doesn't really work! Although [CLLocationManager headingAvailable] is YES, I don't receive any heading updates at all. Strangely, on an iPhone 4, after 30 or so heading updates, locationManager:didUpdateToHeading: is no longer called. This issue is entirely new. The location manager also returns negative numbers for verticalAccuracy, so I'm assuming the altitude it is invalid. Here's how I'm creating the location manager:

CLLocationManager* locationManager = [[CLLocationManager alloc] init];
if([locationManager respondsToSelector:@selector(disallowDeferredLocationUpdates)]) {
   [locationManager disallowDeferredLocationUpdates];
   [locationManager setPausesLocationUpdatesAutomatically:NO];
}
locationManager.headingOrientation = CLDeviceOrientationFaceUp;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.headingFilter = -1;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
[sharedSingleton setLocationManager:locationManager];

sharedSingleton is just my singleton class that handles some odds and ends, including holding onto a reference to the location manager.

If I need to post any more code let me know. I just don't know what might be causing this strange issue. Thanks!

Was it helpful?

Solution 3

Seems the solution was obvious and I overlooked it. The delegate was being set to nil just moments after the location manager was started, which explains why on a slower device like the iPhone 4 a few updates were able to come through before the code setting the delegate to nil was run, but on the iPhone 5 it was instantaneous.

OTHER TIPS

You need to retain "locationManager" in memory somewhere, either as a property of your object or as an instance variable.

What I belive is happening is that you're creating your location manager, and then your method exits and "locationManager" falls out of scope and is magically released by ARC.

So, instead, do something like this:

in your @implementation:

@property (strong) CLLocationManager * locationManager;

and in your @interface:

self.locationManager = [[CLLocationManager alloc] init];
if([self.locationManager respondsToSelector:@selector(disallowDeferredLocationUpdates)]) {
   [self.locationManager disallowDeferredLocationUpdates];
   [self.locationManager setPausesLocationUpdatesAutomatically:NO];
}
self.locationManager.headingOrientation = CLDeviceOrientationFaceUp;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.headingFilter = -1;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;

You could try a few things. First of all, I don't see a startUpdatingHeading call. Maybe you're doing it somewhere else. You should add the locationManager:didFailWithError: method to the delegate to check for errors, and try returning YES in locationManagerShouldDisplayHeadingCalibration: in case it's a calibration issue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top