Files
digital-pilates/utils/healthKitExample.ts
2025-09-17 18:05:11 +08:00

236 lines
7.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* HealthKit Native Module Usage Example
* 展示如何使用HealthKit native module的示例代码
*/
import HealthKitManager, { HealthKitUtils, SleepDataSample } from './healthKit';
export class HealthKitService {
/**
* 初始化HealthKit并请求权限
*/
static async initializeHealthKit(): Promise<boolean> {
try {
// 检查HealthKit是否可用
if (!HealthKitUtils.isAvailable()) {
console.log('HealthKit不可用可能运行在Android设备或模拟器上');
return false;
}
// 请求授权
const result = await HealthKitManager.requestAuthorization();
if (result.success) {
console.log('HealthKit授权成功');
console.log('权限状态:', result.permissions);
// 检查睡眠数据权限
const sleepPermission = result.permissions['HKCategoryTypeIdentifierSleepAnalysis'];
if (sleepPermission === 'authorized') {
console.log('睡眠数据访问权限已获得');
return true;
} else {
console.log('睡眠数据访问权限未获得:', sleepPermission);
return false;
}
} else {
console.log('HealthKit授权失败');
return false;
}
} catch (error) {
console.error('HealthKit初始化失败:', error);
return false;
}
}
/**
* 获取最近的睡眠数据
*/
static async getRecentSleepData(days: number = 7): Promise<SleepDataSample[]> {
try {
const endDate = new Date();
const startDate = new Date();
startDate.setDate(endDate.getDate() - days);
const result = await HealthKitManager.getSleepData({
startDate: startDate.toISOString(),
endDate: endDate.toISOString(),
limit: 100
});
console.log(`获取到 ${result.count} 条睡眠记录`);
return result.data;
} catch (error) {
console.error('获取睡眠数据失败:', error);
return [];
}
}
/**
* 分析睡眠质量
*/
static async analyzeSleepQuality(days: number = 7): Promise<any> {
try {
const sleepData = await this.getRecentSleepData(days);
if (sleepData.length === 0) {
return {
error: '没有找到睡眠数据',
hasData: false
};
}
// 按日期分组
const groupedData = HealthKitUtils.groupSamplesByDate(sleepData);
const dates = Object.keys(groupedData).sort().reverse(); // 最新的日期在前
const analysis = dates.slice(0, days).map(date => {
const daySamples = groupedData[date];
const totalSleepDuration = HealthKitUtils.getTotalSleepDuration(daySamples, new Date(date));
const qualityMetrics = HealthKitUtils.getSleepQualityMetrics(daySamples);
return {
date,
totalSleepDuration,
totalSleepFormatted: HealthKitUtils.formatDuration(totalSleepDuration),
qualityMetrics,
samplesCount: daySamples.length
};
});
// 计算平均值
const validDays = analysis.filter(day => day.totalSleepDuration > 0);
const averageSleepDuration = validDays.length > 0
? validDays.reduce((sum, day) => sum + day.totalSleepDuration, 0) / validDays.length
: 0;
return {
hasData: true,
days: analysis,
summary: {
averageSleepDuration,
averageSleepFormatted: HealthKitUtils.formatDuration(averageSleepDuration),
daysWithData: validDays.length,
totalDaysAnalyzed: days
}
};
} catch (error) {
console.error('睡眠质量分析失败:', error);
return {
error: error instanceof Error ? error.message : String(error),
hasData: false
};
}
}
/**
* 获取昨晚的睡眠数据
*/
static async getLastNightSleep(): Promise<any> {
try {
const today = new Date();
const yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1);
// 设置查询范围昨天下午6点到今天上午12点
const startDate = new Date(yesterday);
startDate.setHours(18, 0, 0, 0);
const endDate = new Date(today);
endDate.setHours(12, 0, 0, 0);
const result = await HealthKitManager.getSleepData({
startDate: startDate.toISOString(),
endDate: endDate.toISOString(),
limit: 50
});
if (result.data.length === 0) {
return {
hasData: false,
message: '未找到昨晚的睡眠数据'
};
}
const sleepSamples = result.data.filter(sample =>
['asleep', 'core', 'deep', 'rem'].includes(sample.categoryType)
);
if (sleepSamples.length === 0) {
return {
hasData: false,
message: '未找到有效的睡眠阶段数据'
};
}
// 找到睡眠的开始和结束时间
const sleepStart = new Date(Math.min(...sleepSamples.map(s => new Date(s.startDate).getTime())));
const sleepEnd = new Date(Math.max(...sleepSamples.map(s => new Date(s.endDate).getTime())));
const totalDuration = sleepSamples.reduce((sum, s) => sum + s.duration, 0);
const qualityMetrics = HealthKitUtils.getSleepQualityMetrics(sleepSamples);
return {
hasData: true,
sleepStart: sleepStart.toISOString(),
sleepEnd: sleepEnd.toISOString(),
totalDuration,
totalDurationFormatted: HealthKitUtils.formatDuration(totalDuration),
qualityMetrics,
samples: sleepSamples,
bedTime: sleepStart.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }),
wakeTime: sleepEnd.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
};
} catch (error) {
console.error('获取昨晚睡眠数据失败:', error);
return {
hasData: false,
error: error instanceof Error ? error.message : String(error)
};
}
}
}
// 使用示例
export const useHealthKitExample = async () => {
console.log('=== HealthKit 使用示例 ===');
// 1. 初始化和授权
const initialized = await HealthKitService.initializeHealthKit();
if (!initialized) {
console.log('HealthKit初始化失败无法继续');
return;
}
// 2. 获取昨晚的睡眠数据
console.log('\n--- 昨晚睡眠数据 ---');
const lastNightSleep = await HealthKitService.getLastNightSleep();
if (lastNightSleep.hasData) {
console.log(`睡眠时间: ${lastNightSleep.bedTime} - ${lastNightSleep.wakeTime}`);
console.log(`睡眠时长: ${lastNightSleep.totalDurationFormatted}`);
if (lastNightSleep.qualityMetrics) {
console.log(`深睡眠: ${lastNightSleep.qualityMetrics.deepSleepPercentage.toFixed(1)}%`);
console.log(`REM睡眠: ${lastNightSleep.qualityMetrics.remSleepPercentage.toFixed(1)}%`);
}
} else {
console.log(lastNightSleep.message || '未找到睡眠数据');
}
// 3. 分析最近一周的睡眠质量
console.log('\n--- 最近一周睡眠分析 ---');
const weeklyAnalysis = await HealthKitService.analyzeSleepQuality(7);
if (weeklyAnalysis.hasData) {
console.log(`平均睡眠时长: ${weeklyAnalysis.summary.averageSleepFormatted}`);
console.log(`有数据的天数: ${weeklyAnalysis.summary.daysWithData}/${weeklyAnalysis.summary.totalDaysAnalyzed}`);
console.log('\n每日睡眠详情:');
weeklyAnalysis.days.forEach((day: any) => {
if (day.totalSleepDuration > 0) {
console.log(`${day.date}: ${day.totalSleepFormatted}`);
}
});
} else {
console.log(weeklyAnalysis.error || '睡眠分析失败');
}
};