3

I want to create an app that can receive and process motion updates in order to understand if the user is stationary, walking, running or is on a transport. I've seen on the reference that CMMotionActivityManager can be useful for me.

The CMMotionActivityManager class provides access to the motion data stored by a device. Motion data reflects whether the user is walking, running, in a vehicle, or stationary for periods of time.

I'm new to app developing and I don't understand how to use the method for starting the updating. The method for doing this is - (void)startActivityUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMMotionActivityHandler)handler. I don't understand what should i write on handler because the reference says:

handler The block to execute when a change in the current type of motion is detected. For information about the parameters of this block, see CMMotionActivityHandler. This property must not be nil.

My implementation is:

- (IBAction)startButtonPressed:(id)sender {
_motionActivityManager = [[CMMotionActivityManager alloc] init];
[_motionActivityManager startActivityUpdatesToQueue:NSOperationQueueDefaultMaxConcurrentOperationCount withHandler:CMMotionActivityHandler];
}

I've already imported the CoreMotion framework But XCode don't recognize CMMotionActivityHandler, where am I wrong? How can I resolve this problem?

Thanks

emattiazzi
  • 366
  • 1
  • 3
  • 12

4 Answers4

4

Sample Code :

[_motionActivityManager startActivityUpdatesToQueue:[[NSOperationQueue alloc] init]
                                          withHandler:
     ^(CMMotionActivity *activity) {

         dispatch_async(dispatch_get_main_queue(), ^{

             if ([activity walking]) {
                 NSLog(@"walking");
             }
     });
}];
Bhavin
  • 27,155
  • 11
  • 55
  • 94
  • Should I define something else in my code above? I've used your code and added some if for activity in order to check if it is automotive, running, unknown but it doesn't work. – emattiazzi Jan 21 '14 at 13:04
  • @mattyahtzee : Of course it won't work on simulator. You have to check in device. – Bhavin Jan 21 '14 at 13:17
4

The highest voted version of this answer is a bit roundabout. It creates a queue, but then uses GCD to execute back on the main queue. Also, many examples put a block within the withHandler parameter, but I find that clunky and doesn't look as clean (from a code formatting perspective).

Here's my example implementation:

@implementation MotionHandler {
@private
    // this is a private variable for this class that is not visible outside
    // (also, iOS handles memory and access management of these faster than properties)
    CMMotionActivityManager *_motionActivityManager;
}

// initialization method, you can do other stuff here too
- (instancetype)init {
    self = [super init];
    if (self) {
        // check to see if the device can handle motion activity
        if ([CMMotionActivityManager isActivityAvailable]) {
            // if so, initialize the activity manager
            _motionActivityManager = [[CMMotionActivityManager alloc] init];
        }
    }
}

- (void)startMotionActivityMonitoring {
    // create the motion activity handler
    CMMotionActivityHandler motionActivityHandler = ^(CMMotionActivity *activity) {
         // TODO motion detected here. Do something.
    }

    // check to see if the motion activity manager exists
    if (_motionActivityManager) {
        // if so, start monitoring activity
        // notice that we add updates to the mainQueue. This will call your handler on the main thread
        [_motionActivityManager startActivityUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:motionActivityHandler];
    }
}

@end
mikeho
  • 6,790
  • 3
  • 34
  • 46
1

//check if availasble on device

BOOL b=  [CMMotionActivityManager isActivityAvailable];;

motionActivityManager=[[CMMotionActivityManager alloc]init];
//register for coremotion notification

 [motionActivityManager startActivityUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMMotionActivity *activity) {

    NSLog(@"Got a core motion update");
    NSLog(@"Current activity date is %f",activity.timestamp);
    NSLog(@"Current activity confidence from a scale of 0 to 2 - 2 being best- is: %ld",activity.confidence);
    NSLog(@"Current activity type is unknown: %i",activity.unknown);
    NSLog(@"Current activity type is stationary: %i",activity.stationary);
    NSLog(@"Current activity type is walking: %i",activity.walking);
    NSLog(@"Current activity type is running: %i",activity.running);
    NSLog(@"Current activity type is cycling: %i",activity.cycling);
    NSLog(@"Current activity type is automotive: %i",activity.automotive);



}];

Please check on device

user3272090
  • 126
  • 5
1

Swift 2.0

_motionActivityManager = CMMotionActivityManager()   
_motionActivityManager.startActivityUpdatesToQueue(NSOperationQueue.mainQueue())
{
    // CMMotionActivity
    activity in

    // do your logic here

}
Aggressor
  • 13,323
  • 24
  • 103
  • 182