GarySabo
GarySabo

Reputation: 6710

How to Check if HealthKit has been authorized

I want to check if HeathKit has been authorized for me to read the user's data, if I'm authorized segue to the workouts, if not pop an alert. But requestAuthorizationToShareTypes always seems to return true? How can I get a reference to whether the user has authorized me or not?

override func viewDidLoad() {
        super.viewDidLoad()

        //1. Set the types you want to read from HK Store
        let healthKitTypesToRead: [AnyObject?] = [
            HKObjectType.workoutType()
        ]


        //2. If the store is not available (for instance, iPad) return an error and don't go on.

        if !HKHealthStore.isHealthDataAvailable() {
            let error = NSError(domain: "com.myndarc.myrunz", code: 2, userInfo: [NSLocalizedDescriptionKey: "HealthKit is not available in this Device"])
                print(error)

            let alertController = UIAlertController(title: "HealthKit Not Available", message: "It doesn't look like HealthKit is available on your device.", preferredStyle: .Alert)
            presentViewController(alertController, animated: true, completion: nil)
            let ok = UIAlertAction(title: "Ok", style: .Default, handler: { (action) -> Void in  })
            alertController.addAction(ok)
                    }

        //3. Request Healthkit Authorization

        let sampleTypes = Set(healthKitTypesToRead.flatMap { $0 as? HKSampleType })

        healthKitStore.requestAuthorizationToShareTypes(sampleTypes, readTypes: nil) {

            (success, error) -> Void in

            if success {
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                                                        self.performSegueWithIdentifier("segueToWorkouts", sender: nil)
                                                    });
            } else {
                print(error)
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                                        self.showHKAuthRequestAlert()
                                    });
            }

        }
    }

Alternatively, I've tried authorizationStatusForType and switched on its enum values but had the same problem in that I'm always authorized.

Upvotes: 27

Views: 19248

Answers (3)

Ashok
Ashok

Reputation: 5655

Currently, there is no way the app can determine whether or not a user has granted permission to read health data.

Below is the description from Apple from authorizationStatus(for:):

To help prevent possible leaks of sensitive health information, your app cannot determine whether or not a user has granted permission to read data. If you are not given permission, it simply appears as if there is no data of the requested type in the HealthKit store. If your app is given share permission but not read permission, you see only the data that your app has written to the store. Data from other sources remains hidden.

Upvotes: 15

Michael
Michael

Reputation: 9904

Note: authorizationStatus is to determine the access status only to write but not to read. There is no option to know whether your app has read access. FYI, https://stackoverflow.com/a/29128231/1996294

Here an example of requesting and checking permission access in HealthKitStore

// Present user with items we need permission for in HealthKit
healthKitStore.requestAuthorization(toShare: typesToShare, read: typesToRead, completion: { (userWasShownPermissionView, error) in

    // Determine if the user saw the permission view
    if (userWasShownPermissionView) {
        print("User was shown permission view")

        // ** IMPORTANT
        // Check for access to your HealthKit Type(s). This is an example of using BodyMass.
        if (self.healthKitStore.authorizationStatus(for: HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.bodyMass)!) == .sharingAuthorized) {
            print("Permission Granted to Access BodyMass")
        } else {
            print("Permission Denied to Access BodyMass")
        }

    } else {
        print("User was not shown permission view")

        // An error occurred
        if let e = error {
            print(e)
        }
    }
})

Upvotes: 14

Nick
Nick

Reputation: 2369

You are misinterpreting what the success flag means in this context. When success is true, all that means is that iOS successfully asked the user about health kit access. It does NOT mean that they responded to that question with a 'yes'.

To determine if they said yes/no, you need to get more specific, and ask health kit if you have permission to read/write the particular type of data you're interested in. From the apple docs on HealthKit:

After requesting authorization, your app is ready to access the HealthKit store. If your app has permission to share a data type, it can create and save samples of that type. You should verify that your app has permission to share data by calling authorizationStatusForType: before attempting to save any samples.

Upvotes: 20

Related Questions