简体   繁体   English

HealthKit 错误:尝试删除 HKQuantitySample 时“找不到要删除的对象”

[英]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:请确保您已执行以下所有步骤:

  1. Add Health entitlement in your app.在您的应用中添加Health entitlement
  2. Add Usage description texts in your Info.plistInfo.plist添加Usage description文本
  3. Request authorization请求授权
  4. Grant the authorization授予授权
  5. Save some valid sample data保存一些有效的样本数据
  6. Query the data查询数据
  7. Check if the result is not empty and is valid检查结果是否不为空且有效
  8. Delete the resulting data删除结果数据

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 授权给HealthKit时错误'(_,_)-> Void'无法转换为'HealthManager' - error '(_, _) -> Void' is not convertible to 'HealthManager' when authorize to HealthKit HealthKit中的错误:错误Domain = com.apple.healthkit代码= 100“无法打开数据库” UserInfo = {NSLocalizedDescription =无法打开数据库} - Error in HealthKit: Error Domain=com.apple.healthkit Code=100 “Failed to open database” UserInfo= {NSLocalizedDescription=Failed to open database} 迁移到Xcode 8和Swift 3.0时,Xcode Healthkit授权函数错误 - Xcode Healthkit authorized function error when migrate to Xcode 8 and Swift 3.0 通过模拟器使用 HealthKit 时无法绕过错误代码 4 - Unable to bypass error code 4 when using HealthKit through the simulator 将HealthKit传播到后端 - Propagating HealthKit Delete to back end 核心数据:尝试删除时出现'NSObjectInaccessibleException'。 - Core Data: 'NSObjectInaccessibleException' when attempting to delete. 尝试取消UILocalNotification时出错 - Error when attempting to cancel a UILocalNotification Healthkit:设置“enableBackgroundDelivery”,但当某些设备上的用户有新的健康数据时,iOS 根本不会唤醒应用程序 - Healthkit: Set up 'enableBackgroundDelivery' but iOS is not at all waking up the app when there is new health data for the user on some devices HealthKit iTunes Connect权利错误 - HealthKit iTunes Connect entitlement error 使用WatchKit和Widget(今天扩展)保存/删除到HealthKit? - Save/Delete to HealthKit With WatchKit and Widget (Today Extension)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM