Files
digital-pilates/docs/BACKGROUND_TASK_TESTING.md
richarjiang d74046498d # 分析方案
## 变更内容总结
1. **iOS后台任务系统重构** - 修复后台任务无法自动运行的问题
2. **日志系统优化** - 改进日志记录机制,添加队列和批量写入
3. **文档新增** - 添加后台任务修复总结和测试指南文档
4. **应用启动优化** - 添加后台任务状态检查和恢复逻辑
5. **版本号更新** - Info.plist版本从1.0.23升级到1.0.24

## 提交信息类型判断
- **主要类型**: `fix` - 这是一个重要的bug修复,解决了iOS后台任务无法自动运行的核心问题
- **作用域**: `ios-background` - 专注于iOS后台任务功能
- **影响**: 这个修复对iOS用户的后台功能至关重要

## 提交信息

fix(ios-background): 修复iOS后台任务无法自动运行的问题

主要修复内容:
- 修复BackgroundTaskBridge任务调度逻辑,改用BGAppRefreshTaskRequest
- 添加任务完成后自动重新调度机制,确保任务持续执行
- 优化应用生命周期管理,移除重复的后台任务调度
- 在应用启动时添加后台任务状态检查和恢复功能
- 将默认任务间隔从30分钟优化为15分钟

次要改进:
- 重构日志系统,添加内存队列和批量写入机制,提升性能
- 添加写入锁和重试机制,防止日志数据丢失
- 新增详细的修复总结文档和测试指南

技术细节:
- 使用BGAppRefreshTaskRequest替代BGProcessingTaskRequest
- 实现任务过期自动重新调度
- 添加任务执行状态监控和恢复逻辑
- 优化错误处理和日志输出

影响范围: iOS后台任务调度、通知推送、应用状态管理
2025-11-04 19:14:53 +08:00

5.3 KiB
Raw Blame History

iOS 后台任务测试指南

修复内容

1. 主要问题

  • 缺少应用生命周期监听:之前没有在应用进入后台时主动调度任务
  • 任务类型不匹配:使用了 BGProcessingTaskRequest 而不是更适合的 BGAppRefreshTaskRequest
  • 调度时机不当:只在初始化时调度一次,没有持续调度
  • 延迟时间过长30分钟的延迟导致测试困难

2. 修复方案

AppDelegate.swift

  • 添加 applicationDidEnterBackground 方法,在应用进入后台时自动调度任务
  • 使用 BGAppRefreshTaskRequest 替代 BGProcessingTaskRequest
  • 设置15分钟的最早开始时间

BackgroundTaskBridge.swift

  • 改进任务处理逻辑,在任务完成或失败时自动重新调度
  • 添加 rescheduleTask 方法确保任务持续执行
  • 取消旧任务请求,避免重复调度
  • 添加更详细的日志输出

backgroundTaskManagerV2.ts

  • 将默认延迟从30分钟减少到15分钟
  • 在初始化完成后立即调度第一次任务
  • 使用 refresh 类型而不是 processing 类型

测试步骤

在真机上测试(推荐)

  1. 准备工作

    # 构建并安装到真机
    npx expo run:ios --device
    
  2. 启用后台应用刷新

    • 打开 iOS 设置 > 通用 > 后台应用刷新
    • 确保总开关已打开
    • 找到 "Out Live" 并启用
  3. 检查后台任务状态

    • 在应用的统计页面,点击"测试后台任务"按钮
    • 查看后台任务状态是否为"可用"
  4. 触发后台任务

    方法一:使用 Xcode 模拟

    # 在 Xcode 中,选择 Debug > Simulate Background Fetch
    # 或者使用命令行
    e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.anonymous.digitalpilates.task"]
    

    方法二:自然触发

    • 将应用切换到后台
    • 等待15-30分钟
    • 系统会在合适的时机自动执行后台任务
  5. 验证任务执行

    • 检查是否收到通知(喝水提醒、挑战鼓励等)
    • 查看 Xcode 控制台日志
    • 检查应用内的最后后台检查时间

使用 Xcode 调试

  1. 连接设备并运行应用

    # 在 Xcode 中打开项目
    open ios/OutLive.xcworkspace
    
  2. 设置断点

    • BackgroundTaskBridge.swifthandle(task:) 方法设置断点
    • AppDelegate.swifthandleBackgroundTask 方法设置断点
  3. 模拟后台任务

    • 运行应用
    • 在 Xcode 菜单中选择 Debug > Simulate Background Fetch
    • 观察断点是否被触发
  4. 查看日志

    [AppDelegate] 后台任务已调度将在15分钟后执行
    [BackgroundTaskBridge] 收到来自 AppDelegate 的后台任务
    [BackgroundTaskBridge] 发送后台任务执行事件到JS
    [BackgroundTaskManagerV2] 收到后台任务事件
    

在模拟器上测试(有限支持)

⚠️ 注意iOS 模拟器对后台任务的支持有限,某些功能可能无法正常工作。

  1. 运行应用

    npx expo run:ios
    
  2. 手动触发测试

    • 在应用的统计页面,点击"测试后台任务"按钮
    • 这会模拟后台任务执行,但不会真正测试系统调度

常见问题

1. 后台任务状态显示"受限制"或"被拒绝"

  • 检查 iOS 设置中的后台应用刷新是否已启用
  • 检查设备的低电量模式是否已关闭
  • 重启设备后重试

2. 后台任务从不执行

  • 确保应用已完全进入后台(不是挂起状态)
  • 等待足够长的时间至少15-30分钟
  • 检查设备是否有足够的电量和网络连接
  • 使用 Xcode 的模拟功能进行测试

3. 日志显示"BGTaskSchedulerErrorDomain 错误1"

  • 这在模拟器上是正常的
  • 在真机上测试以验证功能

4. 任务执行但没有发送通知

  • 检查通知权限是否已授予
  • 检查通知设置是否正确
  • 查看应用日志确认任务逻辑是否正确执行

调试技巧

1. 启用详细日志

在开发环境中,后台任务调试工具会自动启用,提供详细的日志输出。

2. 检查待处理的任务

在应用中调用 getPendingRequests() 查看已调度的后台任务:

const requests = await BackgroundTaskManager.getInstance().getPendingRequests();
console.log('待处理的后台任务:', requests);

3. 查看最后执行时间

const lastCheck = await BackgroundTaskManager.getInstance().getLastBackgroundCheckTime();
console.log('最后后台检查时间:', new Date(lastCheck));

4. 使用系统日志

# 在终端中查看设备日志
xcrun simctl spawn booted log stream --predicate 'subsystem contains "com.anonymous.digitalpilates"'

最佳实践

  1. 在真机上测试:模拟器的后台任务支持有限
  2. 耐心等待:系统调度后台任务需要时间,不要期望立即执行
  3. 监控电量:低电量模式会限制后台任务
  4. 检查设置:确保后台应用刷新已启用
  5. 使用 Xcode 模拟:在开发阶段使用 Xcode 的模拟功能快速测试

参考资料