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

如何通过API复刻健康App中训练记录关联数据的删除提示功能?

复刻健康App删除训练记录时关联数据批量删除功能的实现方案

确实,Apple并没有提供直接复刻健康App中删除Workout时提示删除关联数据的公开便捷API,不过我们可以通过组合现有HealthKit的查询和删除API来实现这个功能,下面是具体的实现步骤和代码示例:

核心思路

健康App的逻辑本质是:先找到与目标Workout关联的所有数据样本,再根据用户选择执行"仅删Workout"或"删除所有关联数据"的操作。我们需要自己实现这两个核心环节。

1. 查询与目标Workout关联的所有数据样本

每个关联到Workout的健康数据样本都会绑定对应的Workout对象,我们可以用HKQuery.predicateForObjectsAssociated(to:)来构建查询谓词,获取所有关联样本:

import HealthKit

class HealthDataManager {
    let healthStore = HKHealthStore()
    
    // 封装查询关联样本的方法
    func fetchAssociatedSamples(for workout: HKWorkout, completion: @escaping ([HKObject]?, Error?) -> Void) {
        // 创建关联查询谓词
        let associationPredicate = HKQuery.predicateForObjectsAssociated(to: workout)
        // 获取App已申请权限的所有健康数据类型(需提前完成权限申请)
        guard let allAuthorizedTypes = healthStore.objectTypes(for: .readWrite) as? [HKSampleType] else {
            completion(nil, NSError(domain: "HealthDataError", code: -1, userInfo: [NSLocalizedDescriptionKey: "无可用的健康数据类型权限"]))
            return
        }
        // 创建复合样本类型用于查询
        let compositeType = HKSampleType.compositeSampleType(for: allAuthorizedTypes)
        
        let query = HKSampleQuery(sampleType: compositeType,
                                  predicate: associationPredicate,
                                  limit: HKObjectQueryNoLimit,
                                  sortDescriptors: nil) { _, samples, error in
            completion(samples, error)
        }
        
        healthStore.execute(query)
    }
}

2. 实现批量删除逻辑

拿到所有关联样本后,使用HKHealthStore.delete(_:completion:)批量删除即可,该方法支持传入HKObject数组:

extension HealthDataManager {
    func batchDeleteObjects(_ objects: [HKObject], completion: @escaping (Bool, Error?) -> Void) {
        healthStore.delete(objects) { success, error in
            completion(success, error)
        }
    }
}

3. 添加用户选择弹窗(复刻健康App的提示逻辑)

在触发删除操作时,弹出弹窗让用户选择删除范围,再根据选择执行对应逻辑:

// 在ViewController中调用的示例
func showDeleteConfirmation(for workout: HKWorkout) {
    let alert = UIAlertController(title: "删除训练记录", message: "是否同时删除关联的健康数据?", preferredStyle: .alert)
    
    // 仅删除训练记录
    alert.addAction(UIAlertAction(title: "仅删除训练记录", style: .destructive) { [weak self] _ in
        guard let self = self else { return }
        self.healthManager.fetchAssociatedSamples(for: workout) { samples, error in
            guard let samples = samples, error == nil else { return }
            // 过滤出仅Workout对象
            let workoutOnly = samples.filter { $0 is HKWorkout }
            self.healthManager.batchDeleteObjects(workoutOnly) { success, _ in
                if success {
                    // 更新UI,比如刷新列表
                }
            }
        }
    })
    
    // 删除训练记录及所有关联数据
    alert.addAction(UIAlertAction(title: "删除训练记录及关联数据", style: .destructive) { [weak self] _ in
        guard let self = self else { return }
        self.healthManager.fetchAssociatedSamples(for: workout) { samples, error in
            guard let samples = samples, error == nil else { return }
            self.healthManager.batchDeleteObjects(samples) { success, _ in
                if success {
                    // 更新UI
                }
            }
        }
    })
    
    alert.addAction(UIAlertAction(title: "取消", style: .cancel))
    
    present(alert, animated: true)
}

注意事项

  • 权限前置:必须提前向用户申请对应健康数据类型的读写权限,否则查询和删除操作会失败。
  • 性能优化:如果关联样本量较大,建议将查询和删除操作放在后台队列执行,避免阻塞主线程影响UI流畅度。
  • 业务过滤:如果你的App不需要删除某些类型的关联数据,可以在查询后额外过滤掉这些类型,比如排除睡眠数据等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:53:22