feat(background-task): 完善iOS后台任务系统并优化断食通知和UI体验

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

这些改进显著提升了应用的稳定性、性能和用户体验,特别是在iOS后台任务执行和断食功能方面。
This commit is contained in:
richarjiang
2025-11-05 11:23:33 +08:00
parent d74046498d
commit ea22901553
12 changed files with 1060 additions and 171 deletions

View File

@@ -0,0 +1,327 @@
# 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)