heikomania heikomania - 3 months ago 25
iOS Question

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!

Answer

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