- 修复iOS后台任务注册时机问题,确保任务能正常触发 - 添加后台任务调试辅助工具和完整测试指南 - 优化断食通知系统,增加防抖机制避免频繁重调度 - 改进断食自动续订逻辑,使用固定时间而非相对时间计算 - 优化统计页面布局,添加身体指标section标题 - 增强饮水详情页面视觉效果,改进卡片样式和配色 - 添加用户反馈入口到个人设置页面 - 完善锻炼摘要卡片条件渲染逻辑 - 增强日志记录和错误处理机制 这些改进显著提升了应用的稳定性、性能和用户体验,特别是在iOS后台任务执行和断食功能方面。
8.1 KiB
8.1 KiB
iOS 后台任务测试指南
问题诊断与修复
已识别的问题
-
AppDelegate 注册时机错误 ✅ 已修复
- 问题:后台任务处理器在
super.application()之后注册 - 修复:移至
super.application()之前注册 - 影响:这是导致任务从未执行的主要原因
- 问题:后台任务处理器在
-
缺少详细日志 ✅ 已修复
- 添加了全面的日志记录
- 改进了错误处理和报告
-
测试机制不完善 ✅ 已修复
- 添加了调试辅助工具
- 提供了诊断命令
在真机上测试后台任务
前置条件
-
设备要求
- iOS 13.0 或更高版本
- 真机(模拟器不支持 BGTaskScheduler)
-
系统设置
设置 > Out Live > 后台App刷新 > 开启 -
开发者设置
设置 > 开发者 > Background Fetch > 频繁
方法 1: 使用 Xcode 模拟后台任务(推荐)
-
在 Xcode 中打开项目
open ios/OutLive.xcworkspace -
运行应用到真机
- 选择真机设备
- 点击 Run (⌘R)
-
暂停应用执行
- 点击 Pause 按钮(或 ⌘⌃Y)
-
在 LLDB 控制台中执行命令
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.anonymous.digitalpilates.task"] -
恢复应用执行
- 点击 Continue 按钮(或 ⌘⌃Y)
-
查看日志
- 在 Xcode Console 中查看后台任务执行日志
- 应该看到
[AppDelegate] ====== 后台任务被触发 ======
方法 2: 使用应用内调试功能
-
在应用中调用诊断工具
import { BackgroundTaskDebugHelper } from "@/services/backgroundTaskDebugHelper"; // 运行完整诊断 const helper = BackgroundTaskDebugHelper.getInstance(); const report = await helper.runFullDiagnostics(); console.log(helper.generateReadableReport(report)); // 手动触发测试任务 await helper.triggerTestTask(); -
在开发者页面添加测试按钮
// 在 app/developer.tsx 中 import { BackgroundTaskManager } from "@/services/backgroundTaskManagerV2"; import { BackgroundTaskDebugHelper } from "@/services/backgroundTaskDebugHelper"; const handleRunDiagnostics = async () => { const helper = BackgroundTaskDebugHelper.getInstance(); const report = await helper.runFullDiagnostics(); Alert.alert("诊断报告", helper.generateReadableReport(report)); }; const handleTriggerTask = async () => { try { await BackgroundTaskManager.getInstance().triggerTaskForTesting(); Alert.alert("成功", "测试任务已触发"); } catch (error) { Alert.alert("错误", error.message); } };
方法 3: 自然触发(等待系统调度)
-
启动应用并确保后台任务已初始化
- 查看启动日志确认初始化成功
- 确认有待处理的任务请求
-
将应用切换到后台
- 按 Home 键或使用手势切换
-
等待系统触发
- iOS 系统会在合适的时机触发后台任务
- 通常在以下情况下:
- 设备空闲
- 网络连接良好
- 电量充足
- 距离上次执行已过最小间隔
-
查看执行记录
const manager = BackgroundTaskManager.getInstance(); const lastExecution = await manager.getLastBackgroundCheckTime(); console.log( "上次执行:", lastExecution ? new Date(lastExecution) : "从未执行" );
验证后台任务执行
检查点 1: 应用启动日志
期望看到:
[BackgroundTaskManagerV2] ====== 开始初始化后台任务管理器 ======
[BackgroundTaskManagerV2] 原生模块可用,开始注册事件监听器
[BackgroundTaskManagerV2] 事件监听器注册完成
[BackgroundTaskManagerV2] 后台刷新状态: available
[BackgroundTaskManagerV2] ✅ 后台任务配置成功
[BackgroundTaskManagerV2] 当前待处理的任务请求数量: 1
[BackgroundTaskManagerV2] ====== 初始化完成 ======
检查点 2: 后台任务触发日志
期望看到:
[AppDelegate] ====== 后台任务被触发 ======
[AppDelegate] 任务标识符: com.anonymous.digitalpilates.task
[BackgroundTaskBridge] ====== 开始处理后台任务 ======
[BackgroundTaskBridge] ✅ 有JS监听器,发送执行事件
[BackgroundTaskManagerV2] ✅ 收到后台任务执行事件
[BackgroundTaskManagerV2] 开始执行后台任务
检查点 3: 任务执行完成日志
期望看到:
[BackgroundTaskManagerV2] 后台任务执行成功
[BackgroundTaskManagerV2] ✅ 后台任务调度成功
常见问题排查
问题 1: 任务从不执行
可能原因:
- 后台刷新权限未启用
- 应用在 Info.plist 中的配置不正确
- 任务标识符不匹配
解决方案:
- 检查系统设置中的后台刷新权限
- 验证 Info.plist 配置:
<key>BGTaskSchedulerPermittedIdentifiers</key> <array> <string>com.anonymous.digitalpilates.task</string> </array> <key>UIBackgroundModes</key> <array> <string>fetch</string> <string>processing</string> </array> - 运行诊断工具检查配置
问题 2: 模拟器上不工作
原因: iOS 模拟器不完全支持 BGTaskScheduler
解决方案: 必须在真机上测试
问题 3: 执行频率低于预期
原因: iOS 系统根据多个因素决定后台任务执行时机:
- 设备使用模式
- 电量状态
- 网络状况
- 应用使用频率
解决方案:
- 使用 Xcode 模拟触发进行测试
- 在生产环境中接受系统的调度策略
- 不要期望后台任务精确按时执行
问题 4: 任务执行时间过短
原因: iOS 通常只给后台任务 30 秒执行时间
解决方案:
- 优化后台任务逻辑,确保快速完成
- 使用异步操作和超时机制
- 在任务过期前完成关键操作
生产环境监控
添加远程日志记录
import { BackgroundTaskManager } from "@/services/backgroundTaskManagerV2";
import AsyncStorage from "@/utils/kvStore";
// 记录后台任务执行历史
async function logBackgroundExecution(success: boolean, duration: number) {
const history = JSON.parse(
(await AsyncStorage.getItem("@bg_task_history")) || "[]"
);
history.push({
timestamp: Date.now(),
success,
duration,
});
// 只保留最近 50 条记录
if (history.length > 50) {
history.shift();
}
await AsyncStorage.setItem("@bg_task_history", JSON.stringify(history));
}
添加性能监控
// 在 backgroundTaskManagerV2.ts 中
private async handleBackgroundExecution(): Promise<void> {
const startTime = Date.now();
try {
await executeBackgroundTasks();
const duration = Date.now() - startTime;
logger.info(`后台任务执行成功,耗时: ${duration}ms`);
// 记录到本地存储或远程服务
await logBackgroundExecution(true, duration);
} catch (error) {
const duration = Date.now() - startTime;
logger.error(`后台任务执行失败,耗时: ${duration}ms`, error);
await logBackgroundExecution(false, duration);
}
}
最佳实践
-
快速执行
- 后台任务应在 30 秒内完成
- 优先处理关键逻辑
- 使用异步操作避免阻塞
-
错误处理
- 捕获所有可能的错误
- 确保任务始终标记为完成
- 在错误情况下也要重新调度
-
电池友好
- 避免密集计算
- 限制网络请求数量
- 使用批处理减少唤醒次数
-
用户体验
- 不要过度依赖后台任务
- 在应用前台时优先更新数据
- 提供手动刷新选项
-
测试覆盖
- 在真机上充分测试
- 模拟各种系统状态(低电量、无网络等)
- 验证长时间运行的稳定性