You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HealthKit删除HKQuantitySample报错:Failed to find some objects for deletion

问题分析与解决方案

你遇到的「Failed to find some objects for deletion」报错,核心原因和解决方向如下:

一、核心原因:Watch与iPhone App的HKSource隔离

即使是同一开发者账号下的Watch App和iPhone App,它们的HKSource是独立的(基于各自的Bundle ID)。默认情况下,HealthKit只允许App删除自身创建的样本,跨设备端的App(Watch→iPhone)无法直接删除对方创建的样本,这是导致报错的首要原因。

二、其他可能的触发因素

  • 权限缺失:iPhone App未申请对应类型的写入权限(删除操作属于写入范畴),仅申请读取权限无法执行删除。
  • 样本包含第三方数据:查询结果中混入了其他App或用户手动添加的样本,当前App无权限删除这些样本,导致批量删除失败。
  • 样本已被删除或日期范围错误:查询到的样本可能已被其他操作删除,或日期Predicate不准确,导致删除时找不到对应对象。
  • 关联HKWorkout未处理:如果这些Distance样本属于某个HKWorkout,而该Workout是Watch App创建的,iPhone App无权限删除Workout时,单独删除样本也可能失败。

三、解决方案

1. 配置HealthKit Source Sharing

在Apple开发者后台为你的App ID开启Source Sharing,允许同一团队下的不同App(Watch+iPhone)共享HealthKit数据访问权限:

  • 登录开发者后台,进入「Certificates, Identifiers & Profiles」
  • 找到你的iPhone和Watch App对应的App ID,编辑HealthKit设置
  • 勾选「Allow Source Sharing」,保存配置后重新生成Provisioning Profile

2. 确保iPhone App拥有正确权限

在请求HealthKit权限时,必须将distanceWalkingRunning加入写入类型数组:

let healthStore = HKHealthStore()
guard let distanceType = HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning) else { return }
let readTypes: Set<HKObjectType> = [distanceType]
let writeTypes: Set<HKObjectType> = [distanceType]

healthStore.requestAuthorization(toShare: writeTypes, read: readTypes) { success, error in
    // 处理权限请求结果
}

3. 过滤本团队的样本

在查询时添加Source过滤,只获取本团队创建的样本,避免尝试删除第三方数据:

// 获取本团队的所有Source Identifier
let teamSources = HKSource.sources(for: .workoutType()).filter { source in
    source.bundleIdentifier.hasPrefix("你的团队Bundle前缀") // 例如 com.yourapp.
}
let sourcePredicate = HKQuery.predicateForObjects(from: Set(teamSources))

// 组合日期和Source条件
let combinedPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate, sourcePredicate])

// 使用combinedPredicate创建查询
let distanceWalkingAndRunningQuery = HKSampleQuery(sampleType: distanceWalkingAndRunningType,
                                                   predicate: combinedPredicate,
                                                   limit: HKObjectQueryNoLimit,
                                                   sortDescriptors: nil)

4. 逐个删除并处理错误

批量删除时只要有一个样本无法删除就会触发整体报错,建议逐个删除并单独处理每个样本的错误:

for sample in unwrappedResults {
    healthStore.delete(sample) { success, error in
        if let error = error {
            print("删除样本失败(startDate: \(sample.startDate)):\(error.localizedDescription)")
        } else if success {
            print("成功删除样本(startDate: \(sample.startDate))")
        }
    }
}

四、额外提示

如果这些Distance样本是HKWorkout的关联样本,优先删除对应的HKWorkout(需要同样的Source Sharing权限),删除Workout会自动清理其关联的所有样本,更高效且避免遗漏。


内容的提问来源于stack exchange,提问作者GarySabo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 11:36:13