CLLocationmanager Heading is not working properly on iPhone 6S and 6S Plus.

I am trying to receive heading (direction in which phone is pointed) for iPhone.

I am trying the code below,


- (void)startHeadingEvents {

if (!self.locManager) {

CLLocationManager* theManager = [[[CLLocationManager alloc] init] autorelease];


// Retain the object in a property.

self.locManager = theManager;

locManager.delegate = self;

}


// Start location services to get the true heading.

locManager.distanceFilter = 1000;

locManager.desiredAccuracy = kCLLocationAccuracyKilometer;

[locManager startUpdatingLocation];


// Start heading updates.

if ([CLLocationManager headingAvailable]) {

locManager.headingFilter = 5;

[locManager startUpdatingHeading];

}

}


- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {

if (newHeading.headingAccuracy < 0)

return;


// Use the true heading if it is valid.

CLLocationDirection theHeading = ((newHeading.trueHeading > 0) ?

newHeading.trueHeading : newHeading.magneticHeading);


self.currentHeading = theHeading;

[self updateHeadingDisplays];

}


Its similar to Apple's iOS developer library and programming guide. The code always returns heading degree between 0 to 10 or 355 to 359. I don't get the values in between.

More, I get this problem only on iPhone 6S and iPhone 6S plus. Otherwise this is perfectly working on iPhone 4S, 5, 5S, 6, 6 Plus. And my all phones are using the latest iOS.

I tried to google it out, but not finding any help or solution. Can anyone please advice me here if something is wrong or needs to be changed?

Thanks.

Replies

Are you asking for permission (e.g. requestWhenInUseAuthorization) prior to starting location updates? The documentation states the true heading won't give valid data unless you've started location updates, and you need to ask permission for that these days.

Are you seeing this issue with 9.2? If so, please file a bug report about this (https://bugreport.apple.com)


If you are indeed seeing this in 9.2, as a workaround you can obtain the calibrated magnetic heading from CoreMotion. To obtain this, subscribe to DeviceMotion with a magnetic reference frame (i.e. CMAttitudeReferenceFrameXMagneticNorthZVertical). This will make a calibrated magnetic field available in CMDeviceMotion (CMCalibratedMagneticField magneticField) which should be similar to the usually expected CLLocationManager heading.


If you are seeing this in 9.1 or below, please try with 9.2. As I said, if you are seeing this issue with 9.2, please file a bug report.