HKHealthStore Extension, deleteSamplesOfType
Following on from my post yesterday about the broken implementation of the HKHealthStore
method deleteObjectsOfType:predicate:withCompletion:
, I’ve put together a gist which provides a fixed method that works with HKSampleType
objects; deleteSamplesOfType:predicate:withCompletion:
import Foundation
import HealthKit
extension HKHealthStore {
func deleteSamplesOfType(sampleType: HKSampleType, predicate: NSPredicate, withCompletion completion: (success: Bool, count: Int, error: NSError?) -> Void) {
let query = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: 0, sortDescriptors: nil) { (query, results, error) -> Void in
if let _ = error {
completion(success: false, count: 0, error: error)
return
}
if let objects = results {
if objects.count == 0 {
completion(success: true, count: 0, error: nil)
} else {
self.deleteObjects(objects, withCompletion: { (success, error) -> Void in
completion(success: error == nil, count: objects.count, error: error)
})
}
} else {
completion(success: true, count: 0, error: nil)
}
}
self.executeQuery(query)
}
}
It simply uses the NSPredicate
within a HKSampleQuery
in order to find any objects that match the HKSampleType
and then deletes them with the HKHealthStore
method deleteObjects:withCompletion:
- this correctly ensures that you are only deleting objects that match both the predicate and type.
By way of example, this simply extends HKHealthStore
so you can do something like this:
let date = NSDate()
let predicate = HKQuery.predicateForSamplesWithStartDate(date.beginningOfDay(), endDate: NSDate().endOfDay(), options: .None)
let stepType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)!
healthStore.deleteSamplesOfType(stepType, predicate: predicate, withCompletion: { (success, count, error) -> Void in
NSLog("deleted \(count) step objects: \(error)")
let stepQuantity = HKQuantity(unit: HKUnit.countUnit(), doubleValue: 9800)
let stepSample = HKQuantitySample(type: stepType, quantity: stepQuantity, startDate: date, endDate: date)
self.healthStore.saveObject(stepSample) { (success, error) -> Void in
}
})
let flightsType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierFlightsClimbed)!
healthStore.deleteSamplesOfType(flightsType, predicate: predicate, withCompletion: { (success, count, error) -> Void in
NSLog("deleted \(count) flight objects: \(error)")
let flightsQuantity = HKQuantity(unit: HKUnit.countUnit(), doubleValue: 15)
let flightsSample = HKQuantitySample(type: flightsType, quantity: flightsQuantity, startDate: date, endDate: date)
self.healthStore.saveObject(flightsSample) { (success, error) -> Void in
}
})
As a reminder, you can file a duplicate of (rdar://22977320) if you’d like to see the original bug fixed but in the meantime the above should allow you to carry on with your HealthKit app without worrying about deleting other data.