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

如何在iPhone应用中通过HealthKit读取、存储ECG数据并处理访问权限

HealthKit ECG功能实现方案与类型标识说明

类型标识差异说明

ECG对应的类型标识是独立的HKElectrocardiogramType,和HKCategoryTypeIdentifier、HKQuantityTypeIdentifier的核心区别如下:

  • HKCategoryTypeIdentifier对应分类类型数据,存储的是预定义的离散枚举值,适用于睡眠阶段、运动类型等场景
  • HKQuantityTypeIdentifier对应数值类型数据,存储的是可量化的数值+对应单位,适用于身高、心率、步数等场景
  • HKElectrocardiogramType是HealthKit专为ECG场景设计的独立样本类型,单条ECG样本不仅包含基础测量值,还附带电压时序数组、采样率、诊断结果、心率等多维度关联数据,无法用单一分类或数值类型承载,因此单独定义。

注意:ECG功能仅支持iOS 14.3及以上版本,且需要对应地区的Apple Watch设备支持ECG功能才能生成数据。


核心实现流程

1. 权限申请

首先在项目Info.plist中添加权限描述键NSHealthShareUsageDescription和NSHealthUpdateUsageDescription,填写ECG数据的使用说明,同时在项目Signing & Capabilities中开启HealthKit能力。
权限申请代码示例:

import HealthKit

let healthStore = HKHealthStore()
// 判断设备是否支持HealthKit和ECG功能
guard HKHealthStore.isHealthDataAvailable(),
      let ecgType = HKObjectType.electrocardiogramType() else {
    return
}
// 申请ECG读取权限
let readTypes: Set<HKObjectType> = [ecgType]
healthStore.requestAuthorization(toShare: nil, read: readTypes) { success, error in
    guard success, error == nil else {
        print("ECG权限申请失败: \(error?.localizedDescription ?? "未知错误")")
        return
    }
    // 权限通过后可执行查询逻辑
}

2. ECG数据查询代码示例

以下为查询过去30天所有ECG记录、并读取对应电压时序数据的示例:

// 构造查询时间范围
let endDate = Date()
let startDate = Calendar.current.date(byAdding: .day, value: -30, to: endDate)!
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictStartDate)

// 构造ECG样本查询
let ecgQuery = HKSampleQuery(
    sampleType: ecgType,
    predicate: predicate,
    limit: HKObjectQueryNoLimit,
    sortDescriptors: [NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)]
) { _, samples, error in
    guard let ecgSamples = samples as? [HKElectrocardiogram], error == nil else {
        print("ECG样本查询失败: \(error?.localizedDescription ?? "未知错误")")
        return
    }
    
    // 遍历所有ECG样本
    for ecg in ecgSamples {
        // 读取ECG基础属性
        print("测量时间: \(ecg.startDate)")
        print("平均心率: \(ecg.averageHeartRate?.doubleValue(for: HKUnit.count().unitDivided(by: HKUnit.minute())) ?? 0) 次/分钟")
        print("诊断分类: \(ecg.classification.rawValue)")
        print("采样率: \(ecg.samplingFrequency.doubleValue(for: HKUnit.hertz())) Hz")
        
        // 查询单条ECG对应的电压时序数据
        let voltageQuery = HKElectrocardiogramQuery(electrocardiogram: ecg) { _, voltageMeasurements, error in
            guard let voltages = voltageMeasurements, error == nil else {
                print("ECG电压数据读取失败: \(error?.localizedDescription ?? "未知错误")")
                return
            }
            // 处理电压数据,单位为微伏,可用于波形绘制、特征计算
            for voltage in voltages {
                let voltageValue = voltage.quantity.doubleValue(for: HKUnit.voltUnit(with: .micro))
                print("时间差: \(voltage.timeSinceSampleStart) s, 电压: \(voltageValue) μV")
            }
        }
        healthStore.execute(voltageQuery)
    }
}
healthStore.execute(ecgQuery)

3. 常见ECG数据计算场景

基于读取到的电压时序数组可实现常见计算逻辑:

  • 心率变异性计算:提取R波峰值,计算相邻R波的时间差标准差
  • 波形异常识别:提取QRS波、P波、T波的宽度、振幅等特征参数
  • 平均电压统计:计算指定时间窗口内的电压平均值,用于降噪或特征提取

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 02:30:02