HealthKit - requestAuthorization(toShare:read:comp

2019-04-10 05:33发布

问题:

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!

回答1:

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