feat: 支持 healthkit
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import dayjs from 'dayjs';
|
||||
import HealthKit from 'react-native-health';
|
||||
import { ensureHealthPermissions } from './health';
|
||||
import HealthKitManager, { HealthKitUtils } from './healthKit';
|
||||
|
||||
// 睡眠阶段枚举
|
||||
export enum SleepStage {
|
||||
@@ -116,54 +115,54 @@ export const fetchSleepSamples = async (date: Date): Promise<SleepSample[]> => {
|
||||
endDate: dateRange.endDate.toISOString(),
|
||||
};
|
||||
|
||||
return new Promise((resolve) => {
|
||||
HealthKit.getSleepSamples(options, (error: string, results: any[]) => {
|
||||
if (error) {
|
||||
console.error('[Sleep] 获取睡眠数据失败:', error);
|
||||
resolve([]); // 返回空数组而非拒绝,以便于处理
|
||||
return;
|
||||
}
|
||||
// return new Promise((resolve) => {
|
||||
// HealthKitManager.(options, (error: string, results: any[]) => {
|
||||
// if (error) {
|
||||
// console.error('[Sleep] 获取睡眠数据失败:', error);
|
||||
// resolve([]); // 返回空数组而非拒绝,以便于处理
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!results || results.length === 0) {
|
||||
console.warn('[Sleep] 未找到睡眠数据');
|
||||
resolve([]);
|
||||
return;
|
||||
}
|
||||
// if (!results || results.length === 0) {
|
||||
// console.warn('[Sleep] 未找到睡眠数据');
|
||||
// resolve([]);
|
||||
// return;
|
||||
// }
|
||||
|
||||
console.log('[Sleep] 获取到原始睡眠样本:', results.length, '条');
|
||||
// console.log('[Sleep] 获取到原始睡眠样本:', results.length, '条');
|
||||
|
||||
// 过滤并转换数据格式
|
||||
const sleepSamples: SleepSample[] = results
|
||||
.filter(sample => {
|
||||
const sampleStart = new Date(sample.startDate).getTime();
|
||||
const sampleEnd = new Date(sample.endDate).getTime();
|
||||
const rangeStart = dateRange.startDate.getTime();
|
||||
const rangeEnd = dateRange.endDate.getTime();
|
||||
// // 过滤并转换数据格式
|
||||
// const sleepSamples: SleepSample[] = results
|
||||
// .filter(sample => {
|
||||
// const sampleStart = new Date(sample.startDate).getTime();
|
||||
// const sampleEnd = new Date(sample.endDate).getTime();
|
||||
// const rangeStart = dateRange.startDate.getTime();
|
||||
// const rangeEnd = dateRange.endDate.getTime();
|
||||
|
||||
return (sampleStart >= rangeStart && sampleStart < rangeEnd) ||
|
||||
(sampleStart < rangeEnd && sampleEnd > rangeStart);
|
||||
})
|
||||
.map(sample => {
|
||||
console.log('[Sleep] 原始睡眠样本:', {
|
||||
startDate: sample.startDate,
|
||||
endDate: sample.endDate,
|
||||
value: sample.value,
|
||||
sourceName: sample.sourceName
|
||||
});
|
||||
// return (sampleStart >= rangeStart && sampleStart < rangeEnd) ||
|
||||
// (sampleStart < rangeEnd && sampleEnd > rangeStart);
|
||||
// })
|
||||
// .map(sample => {
|
||||
// console.log('[Sleep] 原始睡眠样本:', {
|
||||
// startDate: sample.startDate,
|
||||
// endDate: sample.endDate,
|
||||
// value: sample.value,
|
||||
// sourceName: sample.sourceName
|
||||
// });
|
||||
|
||||
return {
|
||||
startDate: sample.startDate,
|
||||
endDate: sample.endDate,
|
||||
value: mapHealthKitSleepValue(sample.value),
|
||||
sourceName: sample.sourceName,
|
||||
sourceId: sample.sourceId || sample.uuid
|
||||
};
|
||||
});
|
||||
// return {
|
||||
// startDate: sample.startDate,
|
||||
// endDate: sample.endDate,
|
||||
// value: mapHealthKitSleepValue(sample.value),
|
||||
// sourceName: sample.sourceName,
|
||||
// sourceId: sample.sourceId || sample.uuid
|
||||
// };
|
||||
// });
|
||||
|
||||
console.log('[Sleep] 过滤后的睡眠样本:', sleepSamples.length, '条');
|
||||
resolve(sleepSamples);
|
||||
});
|
||||
});
|
||||
// console.log('[Sleep] 过滤后的睡眠样本:', sleepSamples.length, '条');
|
||||
// resolve(sleepSamples);
|
||||
// });
|
||||
// });
|
||||
|
||||
} catch (error) {
|
||||
console.error('[Sleep] 获取睡眠样本失败:', error);
|
||||
@@ -181,37 +180,37 @@ export const fetchSleepHeartRateData = async (bedtime: string, wakeupTime: strin
|
||||
endDate: wakeupTime,
|
||||
};
|
||||
|
||||
return new Promise((resolve) => {
|
||||
HealthKit.getHeartRateSamples(options, (error: string, results: any[]) => {
|
||||
if (error) {
|
||||
console.error('[Sleep] 获取心率数据失败:', error);
|
||||
resolve([]);
|
||||
return;
|
||||
}
|
||||
// return new Promise((resolve) => {
|
||||
// HealthKit.getHeartRateSamples(options, (error: string, results: any[]) => {
|
||||
// if (error) {
|
||||
// console.error('[Sleep] 获取心率数据失败:', error);
|
||||
// resolve([]);
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!results || results.length === 0) {
|
||||
console.log('[Sleep] 未找到心率数据');
|
||||
resolve([]);
|
||||
return;
|
||||
}
|
||||
// if (!results || results.length === 0) {
|
||||
// console.log('[Sleep] 未找到心率数据');
|
||||
// resolve([]);
|
||||
// return;
|
||||
// }
|
||||
|
||||
const heartRateData: HeartRateData[] = results
|
||||
.filter(sample => {
|
||||
const sampleTime = new Date(sample.startDate).getTime();
|
||||
const bedtimeMs = new Date(bedtime).getTime();
|
||||
const wakeupTimeMs = new Date(wakeupTime).getTime();
|
||||
return sampleTime >= bedtimeMs && sampleTime <= wakeupTimeMs;
|
||||
})
|
||||
.map(sample => ({
|
||||
timestamp: sample.startDate,
|
||||
value: Math.round(sample.value)
|
||||
}))
|
||||
.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
||||
// const heartRateData: HeartRateData[] = results
|
||||
// .filter(sample => {
|
||||
// const sampleTime = new Date(sample.startDate).getTime();
|
||||
// const bedtimeMs = new Date(bedtime).getTime();
|
||||
// const wakeupTimeMs = new Date(wakeupTime).getTime();
|
||||
// return sampleTime >= bedtimeMs && sampleTime <= wakeupTimeMs;
|
||||
// })
|
||||
// .map(sample => ({
|
||||
// timestamp: sample.startDate,
|
||||
// value: Math.round(sample.value)
|
||||
// }))
|
||||
// .sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
||||
|
||||
console.log('[Sleep] 获取到睡眠心率数据:', heartRateData.length, '个样本');
|
||||
resolve(heartRateData);
|
||||
});
|
||||
});
|
||||
// console.log('[Sleep] 获取到睡眠心率数据:', heartRateData.length, '个样本');
|
||||
// resolve(heartRateData);
|
||||
// });
|
||||
// });
|
||||
|
||||
} catch (error) {
|
||||
console.error('[Sleep] 获取睡眠心率数据失败:', error);
|
||||
@@ -369,8 +368,14 @@ export const getSleepQualityInfo = (sleepScore: number): { description: string;
|
||||
export const fetchCompleteSleepData = async (date: Date): Promise<CompleteSleepData | null> => {
|
||||
try {
|
||||
console.log('[Sleep] 开始获取完整睡眠数据...', dayjs(date).format('YYYY-MM-DD'));
|
||||
// 检查HealthKit是否可用
|
||||
if (!HealthKitUtils.isAvailable()) {
|
||||
console.log('HealthKit不可用,可能运行在Android设备或模拟器上');
|
||||
return null;
|
||||
}
|
||||
|
||||
await ensureHealthPermissions()
|
||||
await HealthKitManager.requestAuthorization()
|
||||
// await ensureHealthPermissions()
|
||||
// 获取睡眠样本
|
||||
const sleepSamples = await fetchSleepSamples(date);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user