Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I try use compass in my ios app. And I have one problem with it. If i implement locationManagerShouldDisplayHeadingCalibration method and return YES in it, then calibration display is showing always. But I should make it like apple maps. I.e. calibration display should be showed sometimes. When compass should be calibration.

share|improve this question
    
I dont think that this is true, I like to force that calibration is always shown, but it will only be shown if device thinks it is needed. Which ios? –  AlexWien Jun 13 '13 at 14:10
    
v6+, and I use OSM maps –  alex_izh Jun 13 '13 at 14:25
    
My experience is if you are outdoors and having a mechanical compass, then I see that ypou have to calibrate the iphone each time you use it. So I want to force the calibration view to come up, even when ios thinks its is not neccessary. But this does not work, you cannot force it to show the calib window. try it out: calibrate it, then leave view, enter again, do you see the calibration view again? –  AlexWien Jun 13 '13 at 14:41
    
I have the opposite problem: the calibration dialog (implemented exactly as yours) is never shown, even if in the exact same location (i.e. seated at my desk) the 'Compass' application continuously shows the dialog. –  Antonio Sesto Feb 24 at 9:20

3 Answers 3

up vote 6 down vote accepted

OK I could not leave a comment so I thought I should leave a reply as Shadow_x99's reply was useful to me.

I am using this improved version of Shadow_x99's response.

- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager{
      if(!manager.heading) return YES; // Got nothing, We can assume we got to calibrate.
      else if( manager.heading < 0 ) return YES; // 0 means invalid heading, need to calibrate
      else if( manager.heading > 5 )return YES; // 5 degrees is a small value correct for my needs, too.
      else return NO; // All is good. Compass is precise enough.
}

Also wanted to say what Shadow_x99 says almost implements the API docs here which states:

If you return NO from this method or do not provide an implementation for it in your delegate, Core Location does not display the heading calibration alert. Even if the alert is not displayed, calibration can still occur naturally when any interfering magnetic fields move away from the device. However, if the device is unable to calibrate itself for any reason, the value in the headingAccuracy property of any subsequent events will reflect the uncalibrated readings.

share|improve this answer

I use the following code:

@property (nonatomic, retain) CLHeading * currentHeading; // Value updated by @selector(locationManager:didUpdateHeading:)
...
...
- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager{
      if( !self.currentHeading ) return YES; // Got nothing, We can assume we got to calibrate.
      else if( self.currentHeading.headingAccuracy < 0 ) return YES; // 0 means invalid heading. we probably need to calibrate
      else if( self.currentHeading.headingAccuracy > 5 )return YES; // 5 degrees is a small value correct for my needs. Tweak yours according to your needs.
      else return NO; // All is good. Compass is precise enough.
}
share|improve this answer

manager.heading is CLHeading. that is why manager.heading > 5 will give a warning. self.currentHeading.headingAccuracy > 5 is the true one.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.