[英]HealthKit Error: “Failed to find some objects for deletion” when attempting to delete HKQuantitySample
I have a workout Apple Watch app that starts an HKWorkout
and saves HKQuantitySamples
(DistanceWalkingRunning samples) into Apple Health using the original Healthkit API (not the newer workout builder).我有一个锻炼 Apple Watch 应用程序,它启动
HKWorkout
并使用原始 Healthkit API(不是较新的锻炼生成器)将HKQuantitySamples
(DistanceWalkingRunning 样本)保存到 Apple Health 中。 I then want to give the user the ability to delete these on the companion iPhone app (eg they forgot to end the workout on the watch).然后,我想让用户能够在配套的 iPhone 应用程序上删除这些内容(例如,他们忘记在手表上结束锻炼)。 No matter which of the 3 methods of deleting the samples I use below I always get this error.
无论我在下面使用的 3 种删除样本的方法中的哪一种,我总是会收到此错误。 I know that an app can only delete samples that were saved by the same app but is the fact that the
HKSource
of the samples is the watch app preventing me from deleting on the iPhone?我知道一个应用程序只能删除由同一应用程序保存的样本,但样本的
HKSource
是阻止我在 iPhone 上删除的手表应用程序这一事实吗? I wouldn't think that would be intended.我不认为这是故意的。 Is there any other reason I am unable to delete these samples?
还有其他原因我无法删除这些样本吗?
private func deleteRunningAndWalkingSamplesFrom(startDate: Date, endDate: Date) {
let healthStore = HKHealthStore()
guard let distanceWalkingAndRunningType:HKQuantityType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning) else {
return
}
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate)
let distanceWalkingAndRunningQuery = HKSampleQuery(sampleType: distanceWalkingAndRunningType,
predicate: predicate,
limit: (HKObjectQueryNoLimit),
sortDescriptors: nil)
{ (query:HKSampleQuery, results:[HKSample]?, error:Error?) -> Void in
if let unwrappedError = error {
print("Error trying to delete distance samples = \(unwrappedError)")
return
}
guard let unwrappedResults = results as? [HKQuantitySample] else {
print("Couldn't cast results as [HKQuantitySample] in deleteRunninAndWalkingSamples")
return
}
//(1) Look through samples and try to delete
// for sample in unwrappedResults {
// healthStore.delete(sample) { success, error in
// if let error = error {
// print("error attempting to delete runningAndWalkinGSample with startDate of \(sample.startDate) error = \(error)")
// }
//
// if success {
// print("successfully delete sample with startDate of \(sample.startDate)")
// }
// }
// }
//(2) Delete objects with predicate
// healthStore.deleteObjects(of: distanceWalkingAndRunningType, predicate: predicate) { success, deleteCount, error in
// if let error = error {
// print("error attempting to delete runningAndWalkinGSamplesFrom shift = \(error)")
// }
//
// if success {
// print("successfully deleted \(deleteCount) samples")
// }
// }
//(3) Delete all samples
healthStore.delete(unwrappedResults) { success, error in
if let error = error {
print("error attempting to delete runningAndWalkinGSamplesFrom shift = \(error)")
}
if success {
print("success deleting runningAndWalkingSamples ")
}
}
}
healthStore.execute(distanceWalkingAndRunningQuery)
}
I've created a sample app, and couldn't reproduce the issue:我创建了一个示例应用程序,但无法重现该问题:
import SwiftUI
import HealthKit
final class HealthManager: ObservableObject {
let quantityType = HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning)!
let healthStore = HKHealthStore()
func requestAuthorization() {
healthStore.requestAuthorization(toShare: [quantityType], read: [quantityType]) { [weak self] success, error in
print(success, error?.localizedDescription ?? "")
self?.createMockData { [weak self] success, error in
print(success, error?.localizedDescription ?? "")
self?.deleteMockData { success, error in
print(success, error?.localizedDescription ?? "")
}
}
}
}
func createMockData(completion: @escaping (Bool, Error?) -> ()) {
let sample = HKQuantitySample(type: quantityType,
quantity: .init(unit: .inch(), doubleValue: 1000),
start: Date().addingTimeInterval(-1000),
end: Date().addingTimeInterval(-10))
healthStore.save(sample, withCompletion: completion)
}
func deleteMockData(completion: @escaping (Bool, Error?) -> ()) {
let predicate = HKQuery.predicateForSamples(withStart: .distantPast, end: .distantFuture)
let distanceWalkingAndRunningQuery = HKSampleQuery(sampleType: quantityType,
predicate: predicate,
limit: HKObjectQueryNoLimit,
sortDescriptors: nil) { [weak self] (query, results, error) in
if let unwrappedError = error {
completion(false, unwrappedError)
return
}
guard let unwrappedResults = results as? [HKQuantitySample] else {
completion(false, NSError(domain: "dom", code: 1, userInfo: [
NSLocalizedDescriptionKey: "Couldn't cast results as [HKQuantitySample] in deleteRunninAndWalkingSamples"
]))
return
}
guard !unwrappedResults.isEmpty else {
completion(false, NSError(domain: "dom", code: 2, userInfo: [
NSLocalizedDescriptionKey: "Nothing to delete"
]))
return
}
self?.healthStore.delete(unwrappedResults, withCompletion: completion)
}
healthStore.execute(distanceWalkingAndRunningQuery)
}
}
@main
struct TestApp: App {
@StateObject var healthManager = HealthManager()
@SceneBuilder var body: some Scene {
WindowGroup {
NavigationView {
ContentView()
.onAppear {
healthManager.requestAuthorization()
}
}
}
WKNotificationScene(controller: NotificationController.self, category: "myCategory")
}
}
Please make sure that you have performed all the following steps:请确保您已执行以下所有步骤:
Health entitlement
in your app.Health entitlement
。Usage description
texts in your Info.plist
Info.plist
添加Usage description
文本
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.