Reputation: 97
So after I read the answer, I now understand that I need to using query to retrive the data in Health and I try to using with codes:
let deletedType = HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier.dietaryCaffeine)
let predicate = HKQuery.predicateForSamples(withStart: dataDate as Date, end: dataDate as Date, options: .strictStartDate)
let findQuery = HKSampleQuery(sampleType: deletedType!, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: nil) {
query, results, error in
if results != nil {
print("\nHere we got not nil on results!\n")
for result in (results as? [HKQuantitySample])! {
let quantity = result.quantity.doubleValue(for: HKUnit.gramUnit(with: .milli))
print(quantity)
}
} else {
print("results are nil")
return
}
}
healthKitStore.execute(findQuery)
I didn't do lot in the resultHander block, I firstly want to check what Data I found, and when I pring the quantity, I got noting, but I did get the "Here we got not nil on resluts" which means the results is not nil. I'm fresh to iOS developing and I check the document of HKHealthSample and cannot find which part of my HKSampleQuery wrong!
I have an app that writes caffeine data into Health via HealthKit Here is the save function
func saveCaffeine(_ caffeineRecorded: Double, dataDate: Date) {
// Set the quantity type to the running/walking distance.
let caffeineType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.dietaryCaffeine)
// Set the unit of measurement to miles.
let caffeineQuantity = HKQuantity(unit: HKUnit.gramUnit(with: .milli), doubleValue: caffeineRecorded)
// Set the official Quantity Sample.
let caffeine = HKQuantitySample(type: caffeineType!, quantity: caffeineQuantity, start: dataDate, end: dataDate)
print("\n to be added: \(caffeine) \n")
// Save the distance quantity sample to the HealthKit Store.
healthKitStore.save(caffeine, withCompletion: { (success, error) -> Void in
if( error != nil ) {
print(error!)
} else {
print("The Caffeine has been recorded! Better go check!")
}
})
}
Then It saved succeddfully, after that I retrive the data when I delete from the table view and pass to another delete function :
func deleteCaffeine(_ caffeineRecorded: Double, dataDate: Date){
let caffeineType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.dietaryCaffeine)
let caffeineQuantity = HKQuantity(unit: HKUnit.gramUnit(with: .milli), doubleValue: caffeineRecorded)
let coffeeBeenDeleted = HKQuantitySample(type: caffeineType!, quantity: caffeineQuantity, start: dataDate, end: dataDate)
print("\n to be deleted: \(coffeeBeenDeleted) \n")
healthKitStore.delete(coffeeBeenDeleted, withCompletion: {(success, error) -> Void in
if (error != nil) {
print(error!)
} else {
print("This caffeine data just been deleted!")
}
})
}
Then I got the error: Error Domain=com.apple.healthkit Code=3 "Failed to find some objects for deletion."
I using Realm to manage the database, I write the data into it that I can then retrieve it.
When I add it the HQuantitySample been printed is:
to be added: 30 mg (2017-10-06 18:36:25 -0400 - 2017-10-06 18:36:25 -0400)
When I delete the same one, the HQuantitySample been printed is: to be deleted: 30 mg (2017-10-06 18:36:25 -0400 - 2017-10-06 18:36:25 -0400)
As I understand, it should retrieve the same data since the amount and date is all right. Am I misunderstand anything about delete in HealthKit
Upvotes: 0
Views: 1341
Reputation: 131
You need to define your specific key in HKMetadataKeySyncIdentifier before you save your data to apple health. And then, you can use HKMetadataKeySyncIdentifier to delete specific health data.
You can try my answer: https://stackoverflow.com/a/69624769/8094919
Upvotes: 0
Reputation: 7343
You can't delete an HKQuantitySample
that was previously saved by constructing a new HKQuantitySample
that has similar properties. If there were two caffeine samples in HealthKit with the same start date, end date, and quantity which one would you expect HealthKit to delete? Each HKObject
is unique and to delete an object you must first find it using a query and then pass the object you got from the query to delete()
.
Upvotes: 1