It's similar to the problem described in Simple iPhone motion detect. The basic setup for CMMotionManager
is described in the Apple docs like Mike Pollard stated in his comment. I recommend especially the Handling Processed Device Motion Data section.
What you then need is CMDeviceMotion.userAcceleration which contains the pure acceleration without gravity.
CMMotionManager *motionManager = [[CMMotionManager alloc] init];
// UPDATE: set interval to 0.02 sec
motionManager.deviceMotionUpdateInterval = 1.0 / 50.0;
[motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]
withHandler:^(CMDeviceMotion *deviceMotion, NSError *error) {
CMAcceleration userAcceleration = deviceMotion.userAcceleration;
double totalAcceleration = sqrt(userAcceleration.x * userAcceleration.x +
userAcceleration.y * userAcceleration.y + userAcceleration.z * userAcceleration.z);
// UPDATE: print debug information
NSLog (@"total=%f x=%f y=%f z=%f", totalAcceleration, userAcceleration.x, userAcceleration.y, userAcceleration.z);
// if(totalAcceleration < SOME_LIMIT) ...
Then proceed like codeplasma has described in his answer above.
Also be aware that the solution might not be precise if used in the underground, bus, etc. because of external accelerations.