# HealthKit Native Module 实现文档 本文档描述了为React Native应用添加HealthKit支持的完整实现,包括授权和睡眠数据获取功能。 ## 功能概述 这个native module提供了以下功能: 1. **HealthKit授权** - 请求用户授权访问健康数据 2. **睡眠数据获取** - 从HealthKit读取用户的睡眠分析数据 ## 文件结构 ``` ios/digitalpilates/ ├── HealthKitManager.swift # Swift native module实现 ├── HealthKitManager.m # Objective-C桥接文件 ├── digitalpilates.entitlements # HealthKit权限配置 └── Info.plist # 权限描述 utils/ ├── healthKit.ts # TypeScript接口定义 ├── healthKitExample.ts # 使用示例 └── health.ts # 现有健康相关工具 ``` ## 权限配置 ### 1. Entitlements文件 `ios/digitalpilates/digitalpilates.entitlements` 已包含: ```xml com.apple.developer.healthkit com.apple.developer.healthkit.background-delivery ``` ### 2. Info.plist权限描述 `ios/digitalpilates/Info.plist` 已包含: ```xml NSHealthShareUsageDescription 应用需要访问您的健康数据(步数、能量消耗、心率变异性等)以展示运动统计和压力分析。 NSHealthUpdateUsageDescription 应用需要更新您的健康数据(体重信息)以记录您的健身进度。 ``` ## Swift实现详情 ### HealthKitManager.swift 核心功能实现: #### 授权方法 ```swift @objc func requestAuthorization( _ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock ) ``` 请求的权限包括: - 睡眠分析 (SleepAnalysis) - 步数 (StepCount) - 心率 (HeartRate) - 静息心率 (RestingHeartRate) - 心率变异性 (HeartRateVariabilitySDNN) - 活动能量消耗 (ActiveEnergyBurned) - 体重 (BodyMass) - 写入权限 #### 睡眠数据获取方法 ```swift @objc func getSleepData( _ options: NSDictionary, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock ) ``` 支持的睡眠阶段: - `inBed` - 在床上 - `asleep` - 睡眠(未分类) - `awake` - 清醒 - `core` - 核心睡眠 - `deep` - 深度睡眠 - `rem` - REM睡眠 ## TypeScript接口 ### 主要接口 ```typescript interface HealthKitManagerInterface { requestAuthorization(): Promise; getSleepData(options?: SleepDataOptions): Promise; } ``` ### 数据类型 ```typescript interface SleepDataSample { id: string; startDate: string; // ISO8601格式 endDate: string; // ISO8601格式 value: number; categoryType: 'inBed' | 'asleep' | 'awake' | 'core' | 'deep' | 'rem' | 'unknown'; duration: number; // 持续时间(秒) source: SleepDataSource; metadata: Record; } ``` ## 使用示例 ### 基本用法 ```typescript import HealthKitManager, { HealthKitUtils } from './utils/healthKit'; // 1. 检查可用性并请求授权 const initHealthKit = async () => { if (!HealthKitUtils.isAvailable()) { console.log('HealthKit不可用'); return false; } try { const result = await HealthKitManager.requestAuthorization(); console.log('授权结果:', result); return result.success; } catch (error) { console.error('授权失败:', error); return false; } }; // 2. 获取睡眠数据 const getSleepData = async () => { try { const result = await HealthKitManager.getSleepData({ startDate: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(), // 7天前 endDate: new Date().toISOString(), // 现在 limit: 100 }); console.log(`获取到 ${result.count} 条睡眠记录`); return result.data; } catch (error) { console.error('获取睡眠数据失败:', error); return []; } }; ``` ### 高级用法 使用提供的 `HealthKitService` 类: ```typescript import { HealthKitService } from './utils/healthKitExample'; // 初始化并获取昨晚睡眠数据 const checkLastNightSleep = async () => { const initialized = await HealthKitService.initializeHealthKit(); if (!initialized) return; const sleepData = await HealthKitService.getLastNightSleep(); if (sleepData.hasData) { console.log(`睡眠时间: ${sleepData.bedTime} - ${sleepData.wakeTime}`); console.log(`睡眠时长: ${sleepData.totalDurationFormatted}`); } }; // 分析一周睡眠质量 const analyzeSleep = async () => { const analysis = await HealthKitService.analyzeSleepQuality(7); if (analysis.hasData) { console.log(`平均睡眠: ${analysis.summary.averageSleepFormatted}`); } }; ``` ## 工具函数 `HealthKitUtils` 类提供了实用的工具方法: - `formatDuration(seconds)` - 格式化时长显示 - `getTotalSleepDuration(samples, date)` - 计算特定日期的总睡眠时长 - `groupSamplesByDate(samples)` - 按日期分组睡眠数据 - `getSleepQualityMetrics(samples)` - 分析睡眠质量指标 - `isAvailable()` - 检查HealthKit是否可用 ## 注意事项 1. **仅iOS支持** - HealthKit仅在iOS设备上可用,Android设备会返回不可用状态 2. **用户权限** - 用户可以拒绝或部分授权,需要优雅处理权限被拒绝的情况 3. **数据可用性** - 并非所有用户都有睡眠数据,特别是没有Apple Watch的用户 4. **隐私保护** - 严格遵循Apple的隐私指南,只请求必要的权限 5. **后台更新** - 已配置后台HealthKit数据传输权限 ## 错误处理 常见错误类型: - `HEALTHKIT_NOT_AVAILABLE` - HealthKit不可用 - `AUTHORIZATION_ERROR` - 授权过程出错 - `AUTHORIZATION_DENIED` - 用户拒绝授权 - `NOT_AUTHORIZED` - 未授权访问特定数据类型 - `QUERY_ERROR` - 数据查询失败 ## 扩展功能 如需添加更多HealthKit数据类型,可以: 1. 在Swift文件中的 `readTypes` 数组添加新的数据类型 2. 实现对应的查询方法 3. 在TypeScript接口中定义新的方法和数据类型 4. 更新Objective-C桥接文件暴露新方法 ## 测试建议 1. 在真实iOS设备上测试(模拟器不支持HealthKit) 2. 使用不同的授权状态测试 3. 测试没有睡眠数据的情况 4. 验证数据格式和时区处理 5. 测试错误场景的处理 ## 相关资源 - [Apple HealthKit文档](https://developer.apple.com/documentation/healthkit) - [React Native Native Modules](https://reactnative.dev/docs/native-modules-ios) - [iOS应用权限指南](https://developer.apple.com/documentation/bundleresources/information_property_list/protected_resources)