Search code examples
ioscmmotionmanager

How to get elevation and magnetic field in iOS


I'm trying to get the elevation value and magnetic field value in iOS. I have been googling for a long time about those subjects, but I couldn't find anything that works properly.

a) When I'm talking about elevation value, I want to get the angle in degrees when I'm moving the top of my mobile up. I have attached an image to make it easier. I have been trying like that, but it doesn't work:

.h

    #import <CoreMotion/CoreMotion.h>

    @property (nonatomic, retain) CMMotionManager *motionManager;

.m
     
    self.motionManager = [[CMMotionManager alloc] init];
    [self.motionManager startMagnetometerUpdates];
    NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
    [self.motionManager startDeviceMotionUpdatesToQueue:myQueue withHandler:^(CMDeviceMotion *motion, NSError *error){
        float degrees = (motion.attitude.roll*180) / M_PI;
        NSLog(@"Value of elevation is: %f", degrees);
    }];

b) About magnetic field, I want to get the impact of devices, magnets, iron, etc that affect the accuracy of my mobile.

  • All the values im getting are not correct by this solution (inside of a kind of NSTimer):
    NSLog(@"magnetometer data -> x: %f", self.motionManager.magnetometerData.magneticField.x);
    NSLog(@"magnetometer data -> y: %f", self.motionManager.magnetometerData.magneticField.y);
    NSLog(@"magnetometer data -> z: %f", self.motionManager.magnetometerData.magneticField.z);
    
    float magneticField = sqrtf( powf(self.motionManager.magnetometerData.magneticField.x, 2) 
    + powf(self.motionManager.magnetometerData.magneticField.y, 2) + 
    powf(self.motionManager.magnetometerData.magneticField.z, 2) );
    
    NSLog(@"magneticField value: %@", magneticField.text);

Any ideas how to figure this out? Thanks


Solution

  • Finally, I got the answer to both questions. Here is the code I am using it. Hope it can help to someone.

    MagneticField: .h

    @property (nonatomic, retain) CLLocationManager *locationManager;
    

    .m

    @synthesize locationManager;
    
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    
    // Starting compass setup
    if(locationManager == nil)
        locationManager = [[CLLocationManager alloc] init];
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    locationManager.delegate = self;
    
    //Start the compass updates.
    if (CLLocationManager.headingAvailable) {
        [locationManager startUpdatingHeading];
        [locationManager startUpdatingLocation];
    }
    else {
        NSLog(@"No Heading Available: ");
        UIAlertView *noCompassAlert = [[UIAlertView alloc] initWithTitle:@"No Compass!" message:@"This device does not have the ability to measure magnetic fields." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [noCompassAlert show];
    }
    }
    
    -(void)locationManager:(CLLocationManager *) manager didUpdateHeading:(CLHeading *)newHeading
    {
    NSLog(@"Magnetic value: %@", [[NSString stringWithFormat:@"%.1f", sqrt(newHeading.x*newHeading.x + newHeading.y*newHeading.y + newHeading.z*newHeading.z)] stringByAppendingFormat:@" µT"]);
    }
    

    Elevation: .h

    @property (nonatomic, retain) CMMotionManager *motionManager;
    

    .m

    @synthesize motionManager;
    
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    // Initializating MotionManager Object    
    motionManager = [[CMMotionManager alloc] init];
    motionManager.showsDeviceMovementDisplay = YES;
    motionManager.deviceMotionUpdateInterval = 20.0/60.0;
    
    // Getting Elevation Value
    CMDeviceMotionHandler  motionHandler = ^ (CMDeviceMotion *motion, NSError *error) {
        CMAttitude *a = motionManager.deviceMotion.attitude;
        NSLog(@"Elevation value, %@:", [[NSString stringWithFormat:@"%.0f", a.pitch*180/M_PI] stringByAppendingFormat:@"˚"]);
    };
    [motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXTrueNorthZVertical toQueue:[NSOperationQueue currentQueue] withHandler:motionHandler];
    }
    

    Cheers.