# iOS 后台任务测试指南 ## 修复内容 ### 1. 主要问题 - **缺少应用生命周期监听**:之前没有在应用进入后台时主动调度任务 - **任务类型不匹配**:使用了 `BGProcessingTaskRequest` 而不是更适合的 `BGAppRefreshTaskRequest` - **调度时机不当**:只在初始化时调度一次,没有持续调度 - **延迟时间过长**:30分钟的延迟导致测试困难 ### 2. 修复方案 #### AppDelegate.swift - 添加 `applicationDidEnterBackground` 方法,在应用进入后台时自动调度任务 - 使用 `BGAppRefreshTaskRequest` 替代 `BGProcessingTaskRequest` - 设置15分钟的最早开始时间 #### BackgroundTaskBridge.swift - 改进任务处理逻辑,在任务完成或失败时自动重新调度 - 添加 `rescheduleTask` 方法确保任务持续执行 - 取消旧任务请求,避免重复调度 - 添加更详细的日志输出 #### backgroundTaskManagerV2.ts - 将默认延迟从30分钟减少到15分钟 - 在初始化完成后立即调度第一次任务 - 使用 `refresh` 类型而不是 `processing` 类型 ## 测试步骤 ### 在真机上测试(推荐) 1. **准备工作** ```bash # 构建并安装到真机 npx expo run:ios --device ``` 2. **启用后台应用刷新** - 打开 iOS 设置 > 通用 > 后台应用刷新 - 确保总开关已打开 - 找到 "Out Live" 并启用 3. **检查后台任务状态** - 在应用的统计页面,点击"测试后台任务"按钮 - 查看后台任务状态是否为"可用" 4. **触发后台任务** 方法一:使用 Xcode 模拟 ```bash # 在 Xcode 中,选择 Debug > Simulate Background Fetch # 或者使用命令行 e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.anonymous.digitalpilates.task"] ``` 方法二:自然触发 - 将应用切换到后台 - 等待15-30分钟 - 系统会在合适的时机自动执行后台任务 5. **验证任务执行** - 检查是否收到通知(喝水提醒、挑战鼓励等) - 查看 Xcode 控制台日志 - 检查应用内的最后后台检查时间 ### 使用 Xcode 调试 1. **连接设备并运行应用** ```bash # 在 Xcode 中打开项目 open ios/OutLive.xcworkspace ``` 2. **设置断点** - 在 `BackgroundTaskBridge.swift` 的 `handle(task:)` 方法设置断点 - 在 `AppDelegate.swift` 的 `handleBackgroundTask` 方法设置断点 3. **模拟后台任务** - 运行应用 - 在 Xcode 菜单中选择 `Debug` > `Simulate Background Fetch` - 观察断点是否被触发 4. **查看日志** ``` [AppDelegate] 后台任务已调度,将在15分钟后执行 [BackgroundTaskBridge] 收到来自 AppDelegate 的后台任务 [BackgroundTaskBridge] 发送后台任务执行事件到JS [BackgroundTaskManagerV2] 收到后台任务事件 ``` ### 在模拟器上测试(有限支持) ⚠️ **注意**:iOS 模拟器对后台任务的支持有限,某些功能可能无法正常工作。 1. **运行应用** ```bash npx expo run:ios ``` 2. **手动触发测试** - 在应用的统计页面,点击"测试后台任务"按钮 - 这会模拟后台任务执行,但不会真正测试系统调度 ## 常见问题 ### 1. 后台任务状态显示"受限制"或"被拒绝" - 检查 iOS 设置中的后台应用刷新是否已启用 - 检查设备的低电量模式是否已关闭 - 重启设备后重试 ### 2. 后台任务从不执行 - 确保应用已完全进入后台(不是挂起状态) - 等待足够长的时间(至少15-30分钟) - 检查设备是否有足够的电量和网络连接 - 使用 Xcode 的模拟功能进行测试 ### 3. 日志显示"BGTaskSchedulerErrorDomain 错误1" - 这在模拟器上是正常的 - 在真机上测试以验证功能 ### 4. 任务执行但没有发送通知 - 检查通知权限是否已授予 - 检查通知设置是否正确 - 查看应用日志确认任务逻辑是否正确执行 ## 调试技巧 ### 1. 启用详细日志 在开发环境中,后台任务调试工具会自动启用,提供详细的日志输出。 ### 2. 检查待处理的任务 在应用中调用 `getPendingRequests()` 查看已调度的后台任务: ```typescript const requests = await BackgroundTaskManager.getInstance().getPendingRequests(); console.log('待处理的后台任务:', requests); ``` ### 3. 查看最后执行时间 ```typescript const lastCheck = await BackgroundTaskManager.getInstance().getLastBackgroundCheckTime(); console.log('最后后台检查时间:', new Date(lastCheck)); ``` ### 4. 使用系统日志 ```bash # 在终端中查看设备日志 xcrun simctl spawn booted log stream --predicate 'subsystem contains "com.anonymous.digitalpilates"' ``` ## 最佳实践 1. **在真机上测试**:模拟器的后台任务支持有限 2. **耐心等待**:系统调度后台任务需要时间,不要期望立即执行 3. **监控电量**:低电量模式会限制后台任务 4. **检查设置**:确保后台应用刷新已启用 5. **使用 Xcode 模拟**:在开发阶段使用 Xcode 的模拟功能快速测试 ## 参考资料 - [Apple 官方文档:Background Tasks](https://developer.apple.com/documentation/backgroundtasks) - [WWDC 2019: Advances in App Background Execution](https://developer.apple.com/videos/play/wwdc2019/707/)