Files
digital-pilates/docs/healthkit-implementation.md
2025-09-17 18:05:11 +08:00

6.5 KiB
Raw Blame History

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 已包含:

<key>com.apple.developer.healthkit</key>
<true/>
<key>com.apple.developer.healthkit.background-delivery</key>
<true/>

2. Info.plist权限描述

ios/digitalpilates/Info.plist 已包含:

<key>NSHealthShareUsageDescription</key>
<string>应用需要访问您的健康数据(步数、能量消耗、心率变异性等)以展示运动统计和压力分析。</string>
<key>NSHealthUpdateUsageDescription</key>
<string>应用需要更新您的健康数据(体重信息)以记录您的健身进度。</string>

Swift实现详情

HealthKitManager.swift

核心功能实现:

授权方法

@objc func requestAuthorization(
  _ resolver: @escaping RCTPromiseResolveBlock,
  rejecter: @escaping RCTPromiseRejectBlock
)

请求的权限包括:

  • 睡眠分析 (SleepAnalysis)
  • 步数 (StepCount)
  • 心率 (HeartRate)
  • 静息心率 (RestingHeartRate)
  • 心率变异性 (HeartRateVariabilitySDNN)
  • 活动能量消耗 (ActiveEnergyBurned)
  • 体重 (BodyMass) - 写入权限

睡眠数据获取方法

@objc func getSleepData(
  _ options: NSDictionary,
  resolver: @escaping RCTPromiseResolveBlock,
  rejecter: @escaping RCTPromiseRejectBlock
)

支持的睡眠阶段:

  • inBed - 在床上
  • asleep - 睡眠(未分类)
  • awake - 清醒
  • core - 核心睡眠
  • deep - 深度睡眠
  • rem - REM睡眠

TypeScript接口

主要接口

interface HealthKitManagerInterface {
  requestAuthorization(): Promise<HealthKitAuthorizationResult>;
  getSleepData(options?: SleepDataOptions): Promise<SleepDataResult>;
}

数据类型

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<string, any>;
}

使用示例

基本用法

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 类:

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. 测试错误场景的处理

相关资源