Reputation: 8855
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!
Upvotes: 0
Views: 905
Reputation: 8855
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.
Upvotes: 0
Reputation: 113777
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.
Upvotes: 0
Reputation: 89569
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;
Upvotes: 1