feat(background-task): 完善iOS后台任务系统并优化断食通知和UI体验
- 修复iOS后台任务注册时机问题,确保任务能正常触发 - 添加后台任务调试辅助工具和完整测试指南 - 优化断食通知系统,增加防抖机制避免频繁重调度 - 改进断食自动续订逻辑,使用固定时间而非相对时间计算 - 优化统计页面布局,添加身体指标section标题 - 增强饮水详情页面视觉效果,改进卡片样式和配色 - 添加用户反馈入口到个人设置页面 - 完善锻炼摘要卡片条件渲染逻辑 - 增强日志记录和错误处理机制 这些改进显著提升了应用的稳定性、性能和用户体验,特别是在iOS后台任务执行和断食功能方面。
This commit is contained in:
@@ -339,37 +339,52 @@ export class BackgroundTaskManagerV2 {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info('[BackgroundTaskManagerV2] ====== 开始初始化后台任务管理器 ======');
|
||||
|
||||
if (!isIosBackgroundModuleAvailable) {
|
||||
logger.warn('[BackgroundTaskManagerV2] iOS 原生后台模块不可用,跳过初始化');
|
||||
logger.warn('[BackgroundTaskManagerV2] Platform:', Platform.OS);
|
||||
this.isInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info('[BackgroundTaskManagerV2] 原生模块可用,开始注册事件监听器');
|
||||
|
||||
const emitter = new NativeEventEmitter(NativeBackgroundModule);
|
||||
|
||||
this.eventSubscription = emitter.addListener(BACKGROUND_EVENT, (payload) => {
|
||||
logger.info('[BackgroundTaskManagerV2] 收到后台任务事件', payload);
|
||||
logger.info('[BackgroundTaskManagerV2] ✅ 收到后台任务执行事件', payload);
|
||||
this.handleBackgroundExecution();
|
||||
});
|
||||
|
||||
this.expirationSubscription = emitter.addListener(EXPIRATION_EVENT, (payload) => {
|
||||
logger.warn('[BackgroundTaskManagerV2] 后台任务在完成前即将过期', payload);
|
||||
logger.warn('[BackgroundTaskManagerV2] ⚠️ 后台任务即将过期', payload);
|
||||
// 处理任务过期情况,确保重新调度
|
||||
this.handleTaskExpiration();
|
||||
});
|
||||
|
||||
logger.info('[BackgroundTaskManagerV2] 事件监听器注册完成');
|
||||
|
||||
try {
|
||||
// 检查后台刷新状态
|
||||
logger.info('[BackgroundTaskManagerV2] 检查后台刷新权限状态...');
|
||||
const status = await this.getStatus();
|
||||
logger.info('[BackgroundTaskManagerV2] 后台刷新状态:', status);
|
||||
|
||||
if (status === 'denied' || status === 'restricted') {
|
||||
logger.warn('[BackgroundTaskManagerV2] 后台刷新被限制或拒绝,后台任务可能无法正常工作');
|
||||
// 不抛出错误,但标记为未完全初始化
|
||||
if (status === 'denied') {
|
||||
logger.error('[BackgroundTaskManagerV2] ❌ 后台刷新被拒绝!');
|
||||
logger.error('[BackgroundTaskManagerV2] 请在 设置 > Out Live > 后台App刷新 中启用');
|
||||
this.isInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (status === 'restricted') {
|
||||
logger.warn('[BackgroundTaskManagerV2] ⚠️ 后台刷新被限制(可能是家长控制)');
|
||||
this.isInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info('[BackgroundTaskManagerV2] 配置后台任务...');
|
||||
await NativeBackgroundModule.configure({
|
||||
identifier: BACKGROUND_TASK_IDENTIFIER,
|
||||
taskType: 'refresh',
|
||||
@@ -377,16 +392,24 @@ export class BackgroundTaskManagerV2 {
|
||||
requiresExternalPower: false,
|
||||
defaultDelay: DEFAULT_RESCHEDULE_INTERVAL_SECONDS,
|
||||
});
|
||||
|
||||
this.isInitialized = true;
|
||||
logger.info('[BackgroundTaskManagerV2] 已初始化并注册 iOS 后台任务');
|
||||
logger.info('[BackgroundTaskManagerV2] ✅ 后台任务配置成功');
|
||||
|
||||
// 立即调度一次后台任务
|
||||
logger.info('[BackgroundTaskManagerV2] 调度首次后台任务...');
|
||||
await this.scheduleNextTask();
|
||||
|
||||
// 检查待处理的任务请求
|
||||
const pendingRequests = await this.getPendingRequests();
|
||||
logger.info('[BackgroundTaskManagerV2] 当前待处理的任务请求数量:', pendingRequests.length);
|
||||
|
||||
if (pendingRequests.length > 0) {
|
||||
logger.info('[BackgroundTaskManagerV2] 待处理任务详情:', JSON.stringify(pendingRequests, null, 2));
|
||||
}
|
||||
|
||||
logger.info('[BackgroundTaskManagerV2] ====== 初始化完成 ======');
|
||||
|
||||
} catch (error: any) {
|
||||
// BGTaskSchedulerErrorDomain 错误码 1 表示后台任务功能不可用
|
||||
// 这在模拟器上是正常的,因为模拟器不完全支持后台任务
|
||||
@@ -395,7 +418,9 @@ export class BackgroundTaskManagerV2 {
|
||||
(errorMessage.includes('错误1') || errorMessage.includes('code 1'));
|
||||
|
||||
if (isBGTaskUnavailable) {
|
||||
logger.warn('[BackgroundTaskManagerV2] 后台任务功能在当前环境不可用(模拟器限制),将在真机上正常工作');
|
||||
logger.warn('[BackgroundTaskManagerV2] ⚠️ 后台任务功能在当前环境不可用');
|
||||
logger.warn('[BackgroundTaskManagerV2] 这是模拟器的正常限制,在真机上会正常工作');
|
||||
logger.warn('[BackgroundTaskManagerV2] 建议:在真机上测试后台任务功能');
|
||||
this.removeListeners();
|
||||
this.isInitialized = false;
|
||||
// 不抛出错误,因为这是预期行为
|
||||
@@ -403,12 +428,15 @@ export class BackgroundTaskManagerV2 {
|
||||
}
|
||||
|
||||
// 其他错误情况,尝试恢复
|
||||
logger.error('[BackgroundTaskManagerV2] 初始化失败,尝试恢复', error);
|
||||
logger.error('[BackgroundTaskManagerV2] ❌ 初始化失败', error);
|
||||
logger.error('[BackgroundTaskManagerV2] 错误详情:', errorMessage);
|
||||
|
||||
try {
|
||||
// 尝试重新初始化一次
|
||||
logger.info('[BackgroundTaskManagerV2] 尝试恢复...');
|
||||
await this.attemptRecovery();
|
||||
logger.info('[BackgroundTaskManagerV2] ✅ 恢复成功');
|
||||
} catch (recoveryError) {
|
||||
logger.error('[BackgroundTaskManagerV2] 恢复失败,放弃初始化', recoveryError);
|
||||
logger.error('[BackgroundTaskManagerV2] ❌ 恢复失败,放弃初始化', recoveryError);
|
||||
this.removeListeners();
|
||||
throw error;
|
||||
}
|
||||
@@ -569,14 +597,41 @@ export class BackgroundTaskManagerV2 {
|
||||
|
||||
async triggerTaskForTesting(): Promise<void> {
|
||||
if (!isIosBackgroundModuleAvailable) {
|
||||
logger.info('[BackgroundTaskManagerV2] 原生模块不可用,直接执行后台任务逻辑');
|
||||
await executeBackgroundTasks();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
logger.info('[BackgroundTaskManagerV2] 尝试模拟触发后台任务...');
|
||||
await NativeBackgroundModule.simulateLaunch();
|
||||
} catch (error) {
|
||||
logger.error('[BackgroundTaskManagerV2] 模拟后台任务触发失败', error);
|
||||
logger.info('[BackgroundTaskManagerV2] ✅ 模拟触发成功');
|
||||
} catch (error: any) {
|
||||
const errorMessage = error?.message || String(error);
|
||||
const errorCode = error?.code || '';
|
||||
|
||||
// 检查是否是模拟器不支持的错误
|
||||
if (errorCode === 'SIMULATOR_NOT_SUPPORTED') {
|
||||
logger.warn('[BackgroundTaskManagerV2] ⚠️ 模拟器不支持后台任务');
|
||||
logger.warn('[BackgroundTaskManagerV2] 这是正常的限制,请在真机上测试');
|
||||
logger.info('[BackgroundTaskManagerV2] 作为替代,直接执行后台任务逻辑...');
|
||||
// 在模拟器上直接执行后台任务逻辑作为测试
|
||||
await executeBackgroundTasks();
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否是监听器未注册的错误
|
||||
if (errorCode === 'NO_LISTENERS') {
|
||||
logger.warn('[BackgroundTaskManagerV2] ⚠️ JS 监听器未注册');
|
||||
logger.warn('[BackgroundTaskManagerV2] 可能是应用还未完全初始化');
|
||||
logger.info('[BackgroundTaskManagerV2] 尝试直接执行后台任务逻辑...');
|
||||
await executeBackgroundTasks();
|
||||
return;
|
||||
}
|
||||
|
||||
logger.error('[BackgroundTaskManagerV2] ❌ 模拟后台任务触发失败', error);
|
||||
logger.error('[BackgroundTaskManagerV2] 错误代码:', errorCode);
|
||||
logger.error('[BackgroundTaskManagerV2] 错误信息:', errorMessage);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user