feat(health): 完善HealthKit权限管理和数据获取系统
- 重构权限管理,新增SimpleEventEmitter实现状态监听 - 实现完整的健身圆环数据获取(活动热量、锻炼时间、站立小时) - 优化组件状态管理,支持实时数据刷新和权限状态响应 - 新增useHealthPermissions Hook,简化权限状态管理 - 完善iOS原生代码,支持按小时统计健身数据 - 优化应用启动时权限初始化流程,避免启动弹窗 BREAKING CHANGE: FitnessRingsCard组件API变更,移除手动传参改为自动获取数据
This commit is contained in:
@@ -221,9 +221,7 @@ export default function PersonalScreen() {
|
||||
<Button
|
||||
variant='default'
|
||||
onPress={() => {
|
||||
console.log(111111);
|
||||
|
||||
// pushIfAuthedElseLogin('/profile/edit')
|
||||
pushIfAuthedElseLogin('/profile/edit')
|
||||
}}
|
||||
modifiers={[
|
||||
frame({
|
||||
@@ -237,10 +235,10 @@ export default function PersonalScreen() {
|
||||
}
|
||||
})
|
||||
]} >
|
||||
<SwiftText size={14} color='black' weight={'medium'}>编辑</SwiftText>
|
||||
<SwiftText size={14} color='black' weight={'medium'}>{isLoggedIn ? '编辑' : '登录'}</SwiftText>
|
||||
</Button>
|
||||
</Host> : <TouchableOpacity style={styles.editButton} onPress={() => pushIfAuthedElseLogin('/profile/edit')}>
|
||||
<Text style={styles.editButtonText}>编辑</Text>
|
||||
<Text style={styles.editButtonText}>{isLoggedIn ? '编辑' : '登录'}</Text>
|
||||
</TouchableOpacity>}
|
||||
|
||||
|
||||
|
||||
@@ -95,28 +95,6 @@ export default function ExploreScreen() {
|
||||
const oxygenSaturation = useMockData ? (mockData?.oxygenSaturation ?? null) : (healthData?.oxygenSaturation ?? null);
|
||||
|
||||
|
||||
const fitnessRingsData = useMockData ? {
|
||||
activeCalories: mockData?.activeCalories ?? 0,
|
||||
activeCaloriesGoal: mockData?.activeCaloriesGoal ?? 350,
|
||||
exerciseMinutes: mockData?.exerciseMinutes ?? 0,
|
||||
exerciseMinutesGoal: mockData?.exerciseMinutesGoal ?? 30,
|
||||
standHours: mockData?.standHours ?? 0,
|
||||
standHoursGoal: mockData?.standHoursGoal ?? 12,
|
||||
} : (healthData ? {
|
||||
activeCalories: healthData.activeEnergyBurned,
|
||||
activeCaloriesGoal: healthData.activeCaloriesGoal,
|
||||
exerciseMinutes: healthData.exerciseMinutes,
|
||||
exerciseMinutesGoal: healthData.exerciseMinutesGoal,
|
||||
standHours: healthData.standHours,
|
||||
standHoursGoal: healthData.standHoursGoal,
|
||||
} : {
|
||||
activeCalories: 0,
|
||||
activeCaloriesGoal: 350,
|
||||
exerciseMinutes: 0,
|
||||
exerciseMinutesGoal: 30,
|
||||
standHours: 0,
|
||||
standHoursGoal: 12,
|
||||
});
|
||||
|
||||
// 用于触发动画重置的 token(当日期或数据变化时更新)
|
||||
const [animToken, setAnimToken] = useState(0);
|
||||
@@ -564,7 +542,6 @@ export default function ExploreScreen() {
|
||||
<FloatingCard style={styles.masonryCard}>
|
||||
<SleepCard
|
||||
selectedDate={currentSelectedDate}
|
||||
onPress={() => pushIfAuthedElseLogin(`/sleep-detail?date=${dayjs(currentSelectedDate).format('YYYY-MM-DD')}`)}
|
||||
/>
|
||||
</FloatingCard>
|
||||
</View>
|
||||
@@ -573,12 +550,7 @@ export default function ExploreScreen() {
|
||||
<View style={styles.masonryColumn}>
|
||||
<FloatingCard style={styles.masonryCard} delay={250}>
|
||||
<FitnessRingsCard
|
||||
activeCalories={fitnessRingsData.activeCalories}
|
||||
activeCaloriesGoal={fitnessRingsData.activeCaloriesGoal}
|
||||
exerciseMinutes={fitnessRingsData.exerciseMinutes}
|
||||
exerciseMinutesGoal={fitnessRingsData.exerciseMinutesGoal}
|
||||
standHours={fitnessRingsData.standHours}
|
||||
standHoursGoal={fitnessRingsData.standHoursGoal}
|
||||
selectedDate={currentSelectedDate}
|
||||
resetToken={animToken}
|
||||
/>
|
||||
</FloatingCard>
|
||||
|
||||
@@ -16,7 +16,7 @@ import { WaterRecordSource } from '@/services/waterRecords';
|
||||
import { store } from '@/store';
|
||||
import { rehydrateUserSync, setPrivacyAgreed } from '@/store/userSlice';
|
||||
import { createWaterRecordAction } from '@/store/waterSlice';
|
||||
import { ensureHealthPermissions } from '@/utils/health';
|
||||
import { ensureHealthPermissions, initializeHealthPermissions } from '@/utils/health';
|
||||
import { DailySummaryNotificationHelpers, MoodNotificationHelpers, NutritionNotificationHelpers } from '@/utils/notificationHelpers';
|
||||
import { clearPendingWaterRecords, syncPendingWidgetChanges } from '@/utils/widgetDataSync';
|
||||
import React from 'react';
|
||||
@@ -44,13 +44,24 @@ function Bootstrapper({ children }: { children: React.ReactNode }) {
|
||||
};
|
||||
|
||||
const initHealthPermissions = async () => {
|
||||
// 初始化 HealthKit 权限
|
||||
// 初始化 HealthKit 权限管理系统
|
||||
try {
|
||||
console.log('开始请求 HealthKit 权限...');
|
||||
await ensureHealthPermissions();
|
||||
console.log('HealthKit 权限初始化完成');
|
||||
console.log('初始化 HealthKit 权限管理系统...');
|
||||
initializeHealthPermissions();
|
||||
|
||||
// 延迟请求权限,避免应用启动时弹窗
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
await ensureHealthPermissions();
|
||||
console.log('HealthKit 权限请求完成');
|
||||
} catch (error) {
|
||||
console.warn('HealthKit 权限请求失败,可能在模拟器上运行:', error);
|
||||
}
|
||||
}, 2000);
|
||||
|
||||
console.log('HealthKit 权限管理初始化完成');
|
||||
} catch (error) {
|
||||
console.warn('HealthKit 权限初始化失败,可能在模拟器上运行:', error);
|
||||
console.warn('HealthKit 权限管理初始化失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user