Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HealthKit - requestAuthorization(toShare:read:completion:) always succeeds

I'm using Xcode 8 beta 6 and I'm requesting access to the Health App. The method requestAuthorization(toShare:read:completion:) which asks for authorization always produces a true when the completion handler returns - success in my code below. Even when I decline everything in the simulator i get a true. Here is my code which handles the authorization. Is something in my code wrong or is this a Xcode bug?

import Foundation
import HealthKit

class HealthManager {
    private let healthStore = HKHealthStore()

    class var sharedInstance: HealthManager {
        struct Singleton {
            static let instance = HealthManager()
        }
        return Singleton.instance
    }

    private var isAuthorized: Bool? = false

    func authorizeHealthKit(completion: ((_ success: Bool) -> Void)!) {
        let writableTypes: Set<HKSampleType> = [HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)!, HKWorkoutType.workoutType(), HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!, HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.activeEnergyBurned)!, HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)!]
        let readableTypes: Set<HKSampleType> = [HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)!, HKWorkoutType.workoutType(), HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!, HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.activeEnergyBurned)!, HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)!]

        guard HKHealthStore.isHealthDataAvailable() else {
            completion(false)
            return
        }

        // Request Authorization
        healthStore.requestAuthorization(toShare: writableTypes, read: readableTypes) { (success, error) in

            if success {
                completion(true)
                self.isAuthorized = true
            } else {
                completion(false)
                self.isAuthorized = false
                print("error authorizating HealthStore. You're propably on iPad \(error?.localizedDescription)")
            }
        }
    }
}

Thanks for your help!

like image 762
heikomania Avatar asked Aug 30 '16 17:08

heikomania


1 Answers

You're misinterpreting what that success flag means. YES means that the permission screen was successfully shown and NO means that there was an error presenting the permissions screen. From Apple's HealthKit documentation:

A Boolean value that indicates whether the request was processed successfully. This value does not indicate whether permission was actually granted. This parameter is NO if an error occurred while processing the request; otherwise, it is YES.

If you want to check if you have access to write data, you need to use authorizationStatus(for:), but note that you cannot determine authorization for reading data.

This method checks the authorization status for saving data.

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.

Documentation is here: https://developer.apple.com/library/ios/documentation/HealthKit/Reference/HKHealthStore_Class/index.html

like image 103
bdjett Avatar answered Sep 28 '22 01:09

bdjett