iosiphoneios8core-motioncmaltimeter

CMAltimeter callback never fires


Using my 6+ I've been trying to read the relative altitude and pressure using CoreMotion's new CMAltimeter. However the callback is never firing. I have a very similar setup which instead uses the accelerometers, gyros, and magnetometers. They all seem to work fine.

Was wondering if anyone out there has managed to get a reading?

- (void)viewDidLoad {
    [super viewDidLoad];

    if([CMAltimeter isRelativeAltitudeAvailable]){
        CMAltimeter *altimeterManager = [[CMAltimeter alloc]init];
        [altimeterManager startRelativeAltitudeUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAltitudeData *altitudeData, NSError *error) {
            // This never fires.
            NSString *data = [NSString stringWithFormat:@"Altitude: %f %f", altitudeData.relativeAltitude.floatValue, altitudeData.pressure.floatValue];
            NSLog(@"%@", data);
            self.altimeterLabel.text = data;
        }];
        NSLog(@"Started altimeter");
        self.altimeterLabel.text = @"-\n-";
    } else {
        NSLog(@"Altimeter not available");
    }
}

I've tried taking this on a quick walk, but there's only one story of altitude to lose/gain around here.


Solution

  • I'm pretty embarrased to answer my own question with such a huge oversight.

    In the original post I had the CMAltimiter declared in the scope of viewDidLoad, thus it goes out of scope and is deallocated. I moved it to be an iVar and the callback now fires.

    #import "ViewController.h"
    @import CoreMotion;
    
    @interface ViewController ()
    @property (nonatomic, strong) CMAltimeter *altimeterManager;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        if([CMAltimeter isRelativeAltitudeAvailable]){
            self.altimeterManager = [[CMAltimeter alloc]init];
            [self.altimeterManager startRelativeAltitudeUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAltitudeData *altitudeData, NSError *error) {
                // This now fires properly
                NSString *data = [NSString stringWithFormat:@"Altitude: %f %f", altitudeData.relativeAltitude.floatValue, altitudeData.pressure.floatValue];
                NSLog(@"%@", data);
                self.altimeterLabel.text = data;
            }];
            NSLog(@"Started altimeter");
            self.altimeterLabel.text = @"-\n-";
        } else {
            NSLog(@"Altimeter not available");
        }
    }