16

If an app requires access to Motion Activity data it asks the user at install. However if the user accidentally answers 'No', then the app will not work.

I am looking for a way to check if the Motion Activity is enabled, so that I can prompt the user to enable if not.

Can someone point me in the right direction code wise please?


Following the info from Doc (Thank you), it seems that Apple do not provide a direct method to check the status of Motion Activity in Privacy. I was able to find out by picking up on the error:-

[stepCounter queryStepCountStartingFrom:[NSDate date]
                                     to:[NSDate date]
                                toQueue:[NSOperationQueue mainQueue]
                            withHandler:^(NSInteger numberOfSteps, NSError *error) {
                                if (error != nil && error.code == CMErrorMotionActivityNotAuthorized) {
                                    // The app isn't authorized to use motion activity support.
}
Julian
  • 9,299
  • 5
  • 48
  • 65
NeilMortonNet
  • 1,500
  • 4
  • 16
  • 36

5 Answers5

15

Apple has a sample project that shows how to check and request access for all the various permissions (including Motion Activity) here. I suggest you take a quick look at that - it's pretty straightforward.

Doc
  • 1,480
  • 2
  • 16
  • 28
  • Hi - I just took a look at this, and it uses [CMMotionActivityManager isActivityAvailable]. I have just tried this, and no matter if it is enabled or not in settings, it always returns TRUE! Very odd, as they say if this returns they state UNAVILABLE. They don't seem to offer a 'Check' but just the initial call to enable. But if it is then disabled it does not re-request! – NeilMortonNet Jan 08 '14 at 21:32
  • 2
    `[CMMotionActivityManager isActivityAvailable]` returns a boolean of whether the device supports the motion data, not if the user has given the app permission to use it. That said, there is no way to re-request permission. You can only see if you have permission and if not, alert the user to go into the Settings app and enable it themselves. – Doc Jan 08 '14 at 21:50
  • The setting can be found in the Settings app under the Privacy section. Select the permission, then you can enable/disable that permission for appropriate apps. – Doc Jan 08 '14 at 21:52
  • 1
    Agreed, but there is no method to check if it is 'Enabled' or 'Disabled'. – NeilMortonNet Jan 08 '14 at 21:56
  • Do any of the function calls made return valid results? No? It's presumably disabled (assuming isActivityAvailable returns true). If I'm not mistaken, that's what the sample project does - starts the activity, attempts something, checks if the attempt succeeded. – Doc Jan 08 '14 at 22:00
  • It seems the sample just tries to access and will request access the first time. It also does a check for isActivityAvailable, but this does not refer to the setting. However, I have found that I can pick up on error and look for CMErrorMotionActivityNotAuthorized! So thank you for pointing me in the right direction. I will update the description with details. – NeilMortonNet Jan 08 '14 at 22:04
  • See @Raymond's answer below. If your app needs to know whether the user has already authorized motion and fitness without querying activity history CMSensorRecorder.isAuthorizedForRecording() is your friend. – Nick Kuh Jan 05 '17 at 17:36
  • @MrNeilM, I believe your comment that there is no method to check this is technically the answer to your question. Which, phooey :( – Alex Hall Jun 29 '17 at 17:09
4

New in iOS 9, CMSensorRecorder(doc link) has a class method to check if your app is authorized for Motion & Fitness:

  • Switft class func isAuthorizedForRecording() -> Bool
  • Objective-c + (BOOL)isAuthorizedForRecording
Raymond
  • 1,172
  • 16
  • 20
  • But, this doesn't indicate whether motion and fitness tracking permission has been enabled by the user. – Nate Oct 25 '16 at 09:30
  • This answers the question "How do I check if my app is authorized to access Motion & Fitness data?--" which wasn't asked. What was asked is how to check if motion activity tracking is enabled in iOS settings for the device (globally). At this writing it seems the correct answer is "there is no provided way to do that," re the post author's own comment. – Alex Hall Jun 29 '17 at 17:12
3

New in iOS 11, CMSSensorRecorder has a static method called authorizationStatus to retrieve it.

+ (CMAuthorizationStatus)authorizationStatus;

Billy
  • 437
  • 1
  • 6
  • 13
  • you also can call CMMotionActivityManager.authorizationStatus() for a status of the activity manager itself. – Hardy_Germany Apr 04 '18 at 14:21
  • iOS 11, ok, but what about pre iOS 11, like iOS 10 for example? Just trying to query some data and to assume that if it doesn't work that the app is not authorised is a bit blunt, isn't it? – drct May 29 '18 at 16:01
  • As of iOS 11, this is the way to achieve this. Pre iOS 11, there wasn’t any ability to check this. Marking as the correct answer, thanks @Billy. – NeilMortonNet Aug 25 '19 at 14:17
1

How about this?

- (void)checkMotionAuth {
    switch ([CMMotionActivityManager authorizationStatus])
    {
        case CMAuthorizationStatusNotDetermined:
        {
            CMMotionActivityManager *manager = [[CMMotionActivityManager alloc]init];
            [manager queryActivityStartingFromDate:[NSDate date]
                                            toDate:[NSDate date]
                                           toQueue:[NSOperationQueue mainQueue]
                                       withHandler:^(NSArray<CMMotionActivity *> * _Nullable activities, NSError * _Nullable error) {

                                           if ([CMMotionActivityManager authorizationStatus] == CMAuthorizationStatusAuthorized)
                                           {
                                               NSLog(@"Authorized");
                                           }
                                           else
                                           {
                                               NSLog(@"Denied");
                                           }
                                       }];
        }
            break;
        case CMAuthorizationStatusRestricted:
        case CMAuthorizationStatusDenied:
        {
            NSLog(@"Denied/Restricted");
        }
            break;
        case CMAuthorizationStatusAuthorized:
        {
            NSLog(@"Authorized");
        }
        default:
            break;
    }
 }
Zaraki
  • 3,720
  • 33
  • 39
  • Indeed. Since iOS 11`+ (CMAuthorizationStatus)authorizationStatus;` is the way to achieve this. However, prior to iOS 11 there was no ability to do this. – NeilMortonNet Aug 25 '19 at 14:13
0

If you are specifically looking for pedometer (step) data, you should use the CMPedometer authorizationStatus() function, which has been available since iOS 11.

let authorizationStatus = CMPedometer.authorizationStatus()

It will return one of 4 CMAuthorizationStatus values:

  • notDetermined: The user has neither granted nor denied access.
  • restricted: Access is denied due to system-wide restrictions (such as in the privacy settings).
  • denied: The user denied access to your application.
  • authorized: You are authorized to access Motion and Fitness data.
Mario Hendricks
  • 727
  • 8
  • 7