If this is of interest to anyone, this is how I got the motion sensors to work under iOS. It has no dependencies so it should work even if you are not using Juce.
You must include the CoreMotion framework. If you are using Projucer don’t do so within XCode, because Projucer will overwrite your changes. Instead, add the word Coremotion in Projucer under Exporters → Xcode(iOS) → Extra System Frameworks.
Since CoreMotion should be turned on only when needed, do so with the start() and stop() functions. Also, create only one MotionManager object. Within iOSMotionManager.mm, set the update interval to whatever you need. According to Apple, their devices support at least 100 Hz.
I think it’s all quite self-explanatory, so here’s the code:
iOSMotionManager.h
class MotionManager
{
public:
MotionManager();
~MotionManager();
void start();
void stop();
double accelerationX = 0;
double accelerationY = 0;
double accelerationZ = 0;
double gravityX = 0;
double gravityY = 0;
double gravityZ = 0;
double rotationX = 0;
double rotationY = 0;
double rotationZ = 0;
double attitudeX = 0;
double attitudeY = 0;
double attitudeZ = 0;
void accelerationChanged (double x, double y, double z);
void gravityChanged (double x, double y, double z);
void rotationChanged (double x, double y, double z);
void attitudeChanged (double x, double y, double z);
private:
void* motionManagerWrapper;
bool isRunning;
};
iOSMotionManager.mm
#ifdef __APPLE__
#import <TargetConditionals.h>
#ifdef TARGET_OS_IOS
#include "iOSMotionManager.h"
#import <CoreMotion/CoreMotion.h>
@interface MotionManagerWrapper : NSObject
{
MotionManager* owner;
}
@property (strong, nonatomic) CMMotionManager *motionManager;
@end
@implementation MotionManagerWrapper
- (void) startMotionManager
{
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 1.0 / 60.0;
[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler:^(CMDeviceMotion *motion, NSError *error)
{
[self outputUserAcceleration :motion.userAcceleration];
[self outputGravity :motion.gravity];
[self outputRotationRate :motion.rotationRate];
[self outputAttitude :motion.attitude];
}];
}
- (void) stopMotionManager
{
[self.motionManager stopGyroUpdates];
[self.motionManager stopAccelerometerUpdates];
self.motionManager = nil;
}
- (void) outputUserAcceleration: (CMAcceleration)acceleration
{
owner->accelerationChanged(acceleration.x, acceleration.y, acceleration.z);
}
- (void) outputGravity: (CMAcceleration)gravity
{
owner->gravityChanged(gravity.x, gravity.y, gravity.z);
}
- (void) outputRotationRate: (CMRotationRate)rotation
{
owner->rotationChanged(rotation.x, rotation.y, rotation.z);
}
- (void) outputAttitude: (CMAttitude *)attitude
{
owner->attitudeChanged(attitude.pitch, attitude.roll, attitude.yaw);
}
- (id) initWithOwner: (MotionManager*) owner_
{
if ((self = [super init]) != nil) { owner = owner_; };
return self;
}
- (void) dealloc
{
[self stopMotionManager];
[super dealloc];
}
@end
MotionManager::MotionManager()
{
isRunning = false;
MotionManagerWrapper* newManager = [[MotionManagerWrapper alloc] initWithOwner: this];
[newManager retain];
motionManagerWrapper = newManager;
}
MotionManager::~MotionManager()
{
[((MotionManagerWrapper*) motionManagerWrapper) release];
}
void MotionManager::start()
{
if (!isRunning)
{
[(MotionManagerWrapper*) motionManagerWrapper startMotionManager];
isRunning = true;
}
}
void MotionManager::stop()
{
[(MotionManagerWrapper*) motionManagerWrapper stopMotionManager];
isRunning = false;
}
void MotionManager::accelerationChanged (double x, double y, double z)
{
accelerationX = x;
accelerationY = y;
accelerationZ = z;
}
void MotionManager::gravityChanged (double x, double y, double z)
{
gravityX = x;
gravityY = y;
gravityZ = z;
}
void MotionManager::rotationChanged (double x, double y, double z)
{
rotationX = x;
rotationY = y;
rotationZ = z;
}
void MotionManager::attitudeChanged (double x, double y, double z)
{
attitudeX = x;
attitudeY = y;
attitudeZ = z;
}
#endif
#endif
By the way, the code above was adapted from here (thanks to hanley for posting):
Now, does anyone know how to get this working in Android and would like to share? That would be great!
