I am using M7/M8 chip's MotionActivity in a variety of ways, including for step counting. For step counting, I both query for the day's steps, and request ongoingly the step count as they occur realtime.
Currently before I do this I check [CMStepCounter isStepCountingAvailable], as well as a local override flag, before proceeding with this code. I assumed isStepCountingAvailable would return FALSE if authorization for motionActivity was not granted. This does not seem to be the case, it appears to be more of a hardware detection only. I cannot seem to find other methods that detect whether authorization was granted for this.
What this means is that startStepCountingUpdatesToQueue and queryStepCountStartingFrom both run, and return blocks, but always return an error code. Specifically CMErrorDomain code 105.
Is there a better way for me to determine if motionActivity has not been authorized? I've got some fallback code but I'd prefer a boolean check beforehand, instead of an error code in the return block.
if (self.useM7IfAvailable && [CMStepCounter isStepCountingAvailable]){
self.cmStepCounter = [[CMStepCounter alloc] init];
[self.cmStepCounter startStepCountingUpdatesToQueue:self.operationQueue updateOn:1.0 withHandler:^(NSInteger numberOfSteps, NSDate *timestamp, NSError *error){
if(!error){
// do something with numberOfSteps
} else {
// not authorized: CMErrorDomain code 105
}
}];
}
[self.cmStepCounter queryStepCountStartingFrom:dayStart to:dayEnd toQueue:_operationQueue withHandler:^(NSInteger numberOfSteps, NSError *error) {
if(!error){
// do something with numberOfSteps
} else {
// not authorized: CMErrorDomain code 105
}
}];
You're doing it correctly by checking for the error. Per the docs (https://developer.apple.com/library/ios/documentation/coremotion/reference/cmmotionmanager_class/index.html#//apple_ref/c/tdef/CMError) you'll receive back CMErrors with Error Code 105 like you've seen.
Unfortunately there's no way to check ahead-of-time to see if you're authorized or not, but this follows Apple's paradigms with other Core-level frameworks that require authorization, like CoreLocation. The reasoning is you can be in the middle of getting motion steps while in the background, and the user can then disable your motion access, which you'll have to react to that event in probably the same way you'd react to not being authorized in the first place.