Files
digital-pilates/docs/background-task-testing-guide.md
richarjiang ea22901553 feat(background-task): 完善iOS后台任务系统并优化断食通知和UI体验
- 修复iOS后台任务注册时机问题,确保任务能正常触发
- 添加后台任务调试辅助工具和完整测试指南
- 优化断食通知系统,增加防抖机制避免频繁重调度
- 改进断食自动续订逻辑,使用固定时间而非相对时间计算
- 优化统计页面布局,添加身体指标section标题
- 增强饮水详情页面视觉效果,改进卡片样式和配色
- 添加用户反馈入口到个人设置页面
- 完善锻炼摘要卡片条件渲染逻辑
- 增强日志记录和错误处理机制

这些改进显著提升了应用的稳定性、性能和用户体验,特别是在iOS后台任务执行和断食功能方面。
2025-11-05 11:23:33 +08:00

328 lines
8.1 KiB
Markdown
Raw Permalink 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.

# iOS 后台任务测试指南
## 问题诊断与修复
### 已识别的问题
1. **AppDelegate 注册时机错误** ✅ 已修复
- 问题:后台任务处理器在 `super.application()` 之后注册
- 修复:移至 `super.application()` 之前注册
- 影响:这是导致任务从未执行的主要原因
2. **缺少详细日志** ✅ 已修复
- 添加了全面的日志记录
- 改进了错误处理和报告
3. **测试机制不完善** ✅ 已修复
- 添加了调试辅助工具
- 提供了诊断命令
## 在真机上测试后台任务
### 前置条件
1. **设备要求**
- iOS 13.0 或更高版本
- 真机(模拟器不支持 BGTaskScheduler
2. **系统设置**
```
设置 > Out Live > 后台App刷新 > 开启
```
3. **开发者设置**
```
设置 > 开发者 > Background Fetch > 频繁
```
### 方法 1: 使用 Xcode 模拟后台任务(推荐)
1. **在 Xcode 中打开项目**
```bash
open ios/OutLive.xcworkspace
```
2. **运行应用到真机**
- 选择真机设备
- 点击 Run (⌘R)
3. **暂停应用执行**
- 点击 Pause 按钮(或 ⌘⌃Y
4. **在 LLDB 控制台中执行命令**
```lldb
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.anonymous.digitalpilates.task"]
```
5. **恢复应用执行**
- 点击 Continue 按钮(或 ⌘⌃Y
6. **查看日志**
- 在 Xcode Console 中查看后台任务执行日志
- 应该看到 `[AppDelegate] ====== 后台任务被触发 ======`
### 方法 2: 使用应用内调试功能
1. **在应用中调用诊断工具**
```typescript
import { BackgroundTaskDebugHelper } from "@/services/backgroundTaskDebugHelper";
// 运行完整诊断
const helper = BackgroundTaskDebugHelper.getInstance();
const report = await helper.runFullDiagnostics();
console.log(helper.generateReadableReport(report));
// 手动触发测试任务
await helper.triggerTestTask();
```
2. **在开发者页面添加测试按钮**
```typescript
// 在 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: 自然触发(等待系统调度)
1. **启动应用并确保后台任务已初始化**
- 查看启动日志确认初始化成功
- 确认有待处理的任务请求
2. **将应用切换到后台**
- 按 Home 键或使用手势切换
3. **等待系统触发**
- iOS 系统会在合适的时机触发后台任务
- 通常在以下情况下:
- 设备空闲
- 网络连接良好
- 电量充足
- 距离上次执行已过最小间隔
4. **查看执行记录**
```typescript
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 中的配置不正确
- 任务标识符不匹配
**解决方案:**
1. 检查系统设置中的后台刷新权限
2. 验证 Info.plist 配置:
```xml
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.anonymous.digitalpilates.task</string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
</array>
```
3. 运行诊断工具检查配置
### 问题 2: 模拟器上不工作
**原因:**
iOS 模拟器不完全支持 BGTaskScheduler
**解决方案:**
必须在真机上测试
### 问题 3: 执行频率低于预期
**原因:**
iOS 系统根据多个因素决定后台任务执行时机:
- 设备使用模式
- 电量状态
- 网络状况
- 应用使用频率
**解决方案:**
- 使用 Xcode 模拟触发进行测试
- 在生产环境中接受系统的调度策略
- 不要期望后台任务精确按时执行
### 问题 4: 任务执行时间过短
**原因:**
iOS 通常只给后台任务 30 秒执行时间
**解决方案:**
- 优化后台任务逻辑,确保快速完成
- 使用异步操作和超时机制
- 在任务过期前完成关键操作
## 生产环境监控
### 添加远程日志记录
```typescript
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));
}
```
### 添加性能监控
```typescript
// 在 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);
}
}
```
## 最佳实践
1. **快速执行**
- 后台任务应在 30 秒内完成
- 优先处理关键逻辑
- 使用异步操作避免阻塞
2. **错误处理**
- 捕获所有可能的错误
- 确保任务始终标记为完成
- 在错误情况下也要重新调度
3. **电池友好**
- 避免密集计算
- 限制网络请求数量
- 使用批处理减少唤醒次数
4. **用户体验**
- 不要过度依赖后台任务
- 在应用前台时优先更新数据
- 提供手动刷新选项
5. **测试覆盖**
- 在真机上充分测试
- 模拟各种系统状态(低电量、无网络等)
- 验证长时间运行的稳定性
## 参考资源
- [Apple BGTaskScheduler 文档](https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler)
- [WWDC 2019: Advances in App Background Execution](https://developer.apple.com/videos/play/wwdc2019/707/)
- [iOS 后台执行最佳实践](https://developer.apple.com/documentation/backgroundtasks/starting_and_terminating_tasks_during_development)