如何在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
相关产品推荐
相关产品推荐

