Reputation:
Game.m
#import "Game.h"
#import "CoreMotion.h"
@implementation Game
- (id) init
{
self = [super init];
self.stopButtonPressed = NO;
return self;
}
-(void) play
{
CMMotionManager *motionManager;
motionManager = [[CMMotionManager alloc] init];
motionManager.deviceMotionUpdateInterval = 1.f/10.f;
[motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler:^(CMDeviceMotion *motion, NSError *error)
{
NSLog(@"--------------> %i %i", motionManager.deviceMotionActive , motionManager.deviceMotionAvailable);
NSLog(@"Degrees : %F",atan(motion.magneticField.field.y/fabs(motion.magneticField.field.x)) * 180.0 / M_PI);
}
];
}
MyViewController.m
#import "MyViewController.h"
#import "Game.h"
@interface MyViewController()
{
Game *game;
}
@end
@implementation MyViewController
-(void) viewDidLoad
{
game = [[Game alloc] init];
}
- (IBAction)playPressed:(UIButton *)sender
{
// using a separate thread
//[game performSelectorInBackground:@selector(play) withObject:nil];
// not using a separate thread
[game play] ;
}
- (IBAction)stopPressed:(UIButton *)sender
{
game.stopButtonPressed = YES;
}
@end
Upvotes: 2
Views: 1411
Reputation: 34912
You need to hold onto the CMMotionManager
. So make an instance variable for it. For example:
#import "Game.h"
#import "CoreMotion.h"
@interface Game ()
@property (nonatomic, strong) CMMotionManager *motionManager;
@end
@implementation Game
@synthesize motionManager = _motionManager;
- (id) init
{
self = [super init];
self.stopButtonPressed = NO;
return self;
}
-(void) play
{
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 1.f/10.f;
[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler:^(CMDeviceMotion *motion, NSError *error)
{
NSLog(@"--------------> %i %i", self.motionManager.deviceMotionActive , self.motionManager.deviceMotionAvailable);
NSLog(@"Degrees : %F",atan(motion.magneticField.field.y/fabs(motion.magneticField.field.x)) * 180.0 / M_PI);
}
];
}
The problem is that your CMMotionManager
that you're creating is being deallocated at the end of the play
method since nothing is holding onto it. So the handler never gets called back because your motion manager has gone away.
Upvotes: 1
Reputation: 7493
BTW One possibility is that the device you are running may not even have a magnetometer. See magnetometer-for-compass-on-ipod-touch-4g Where I point to apple-devices-with-magnetometer
Upvotes: 0
Reputation: 3857
the magnetic field value is not available immediately after you call the method startDeviceMotionUpdates
. You need to try to retrive the value in a later point (i.e. using a NSTimer
and checking for updates.
Although this should work it isn't a good practice. If you only need the magnetic field value you should take a look at the documentation of CMMotionManager
and use the method startMagnetometerUpdatesToQueue:withHandler: like the following:
[motionManager startMagnetometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMMagnetometerData *magnetometerData, NSError *error) {
CMMagneticField field = magnetometerData.magneticField;
NSLog(@"x: %f y:%f z:%f", field.x, field.y, field.z);
}];
cheers, anka
Upvotes: 1