When trying to set an observer query for Healthkit, for a lot of users I'm getting an error of Authorization not Determined
.
After researching for a bit I saw that an error like that should only happen when trying to write (share) data to Healthkit. According to Apple HK Documentation - When trying to read data that the user did not grant permissions to I shouldn't get any data at all (without any errors) as if there is no new data.
Here's the code I use to set the observer queries:
class func setObserver(healthKitManager manager: HealthKitManager, forType type: HKSampleType?, withPredicateAfterFetching predicate: NSPredicate?) {
guard type != nil && manager.healthStore != nil else {
return
}
let query = HKObserverQuery.init(sampleType: type!, predicate: nil) { (query, completionHandler, error) in
guard error == nil else {
SimpleEvent(name: "HKObserverQuery failed", param: "type:\(type!.identifier), error: \(error!.localizedDescription)").fire()
return
}
let anchoredQuery = HKAnchoredObjectQuery.init(type: type!, predicate: predicate, anchor: manager.getHealthDataAnchor(forType: type!), limit: HKObjectQueryNoLimit, resultsHandler: { (query, results, deletedObjects, newAnchor, error) in
guard error == nil else {
SimpleEvent(name: "HKAnchoredQuery failed", param: "type:\(type!.identifier), error: \(error!.localizedDescription)").fire()
return
}
\\ Code that saves the HK Data
completionHandler()
})
manager.healthStore!.execute(anchoredQuery)
}
manager.healthStore!.execute(query)
manager.observerQueries.append(query)
}
The error is caught on the HKObserverQuery failed
event.
As I mentioned the permission request should not affect the data reading but here's that code anyway:
func requestAuthorizationToShareTypesAndReadTypes(withSuccess successBlock: @escaping () -> Void, failure failureBlock: @escaping () -> Void) {
self.healthStore?.requestAuthorization(toShare: writeDataTypes as! Set<HKSampleType>, read: readDataTypes as! Set<HKObjectType>, completion: { (success, error) in
if !success || error != nil {
SimpleEvent.init(name: "HK-requestAuthorization", param: error!.localizedDescription)
NSLog("You didn't allow HealthKit to access these read/write data types. The error was: %@.", error as! NSError);
failureBlock()
return;
}
self.userHaveBeenPromptWithPermissionsScreenAtLeastOnce = true
self.enableBackgroundDelivery()
successBlock()
})
}
And Here's the part where I enable background delivery
func enableBackgroundDelivery() {
for type in self.readDataTypes! {
if let type = type as? HKSampleType {
self.enableBackgroundDelivery(forSampleType: type)
}
}
}
func enableBackgroundDelivery(forSampleType type:HKSampleType) {
self.healthStore?.enableBackgroundDelivery(for: type, frequency: HKUpdateFrequency.immediate, withCompletion: { (success, error) in
if error != nil {
print(String.init(format: "HK-BackgoundError: error:%@, user: %@, type: %@", error!.localizedDescription, NRManager.shared().username, type.identifier))
}
})
}
Authorization is required to read data from HealthKit. If you are receiving an error indicating authorization is not determined, then that indicates the user has not been prompted to authorize your app to either read or write samples of the type you are querying for.