iOS开发如何向BGTaskScheduler提交的后台任务传递JSON参数
iOS BGTaskScheduler 后台任务传递JSON参数实现方案
iOS的BGTaskScheduler管理的后台任务(包含BGProcessingTaskRequest、BGAppRefreshTaskRequest)本身设计上就不支持直接在请求实例上挂载自定义参数——和Android WorkManager会把setInputData绑定的参数随任务实例调度不同,iOS要求你在App启动阶段就提前注册对应任务标识的启动回调,系统调度任务时直接调用提前注册的回调,不会回传你提交请求时的实例对象。
要实现和Android传参同等的效果,采用提交前本地持久化参数、任务启动时读取参数、任务结束后清理参数的方案即可,具体实现如下:
实现步骤
1. 提交任务前持久化JSON参数
根据JSON体积选择合适的存储方式:
- 体积在几KB以内的普通JSON字符串:直接用
UserDefaults存储即可 - 体积较大的JSON内容:存入沙盒
tmp/Library/Caches目录下的临时文件,参数只保留文件路径
如果同一任务标识同一时间只会提交一个待调度任务,直接用固定key存储即可,示例代码:
import BackgroundTasks let taskIdentifier = SwiftWorkmanagerPlugin.defaultBGProcessingTaskIdentifier let inputJson: String = // 你需要传递的JSON字符串 let paramStoreKey = "kBGTaskInput_\(taskIdentifier)" // 先持久化参数 UserDefaults.standard.set(inputJson, forKey: paramStoreKey) // 构造并提交任务请求 let request = BGProcessingTaskRequest(identifier: taskIdentifier) // 按需配置网络、外接电源等约束 // request.requiresNetworkConnectivity = true // request.requiresExternalPower = false do { try BGTaskScheduler.shared.submit(request) } catch { // 提交失败必须清理已存的参数,避免脏数据 UserDefaults.standard.removeObject(forKey: paramStoreKey) print("后台任务提交失败: \(error)") }
如果同一任务标识需要同时提交多个待调度任务,维护一个FIFO队列持久化存储参数即可:提交时将参数追加到队列尾部,任务启动时取队首参数使用,避免多任务参数覆盖。
2. 任务启动时读取参数,执行完成后清理
在App启动阶段(一般是AppDelegate的application(_:didFinishLaunchingWithOptions:)方法中)提前注册任务回调,系统调度任务时读取对应参数执行业务,任务结束后清理存储的参数:
// App启动时注册任务回调 BGTaskScheduler.shared.register( forTaskWithIdentifier: SwiftWorkmanagerPlugin.defaultBGProcessingTaskIdentifier, using: nil ) { task in let paramStoreKey = "kBGTaskInput_\(SwiftWorkmanagerPlugin.defaultBGProcessingTaskIdentifier)" // 读取传入的JSON参数 guard let jsonParam = UserDefaults.standard.string(forKey: paramStoreKey) else { // 无有效参数直接结束任务 task.setTaskCompleted(success: false) return } // 配置任务过期回调,做清理工作 task.expirationHandler = { UserDefaults.standard.removeObject(forKey: paramStoreKey) task.setTaskCompleted(success: false) } // 在这里执行业务逻辑,jsonParam就是你传入的JSON字符串 // do your work... // 业务执行完成后清理参数,标记任务完成 UserDefaults.standard.removeObject(forKey: paramStoreKey) task.setTaskCompleted(success: true) }
注意事项
- 不要通过参数传递超大内容,iOS后台任务对内存、沙盒IO有严格限制,大体积数据优先存文件,只传文件路径
- 所有异常分支(提交失败、任务过期、任务执行报错)都要及时清理存储的参数,避免下次任务启动读取到旧的脏数据
- 如果需要支持任务取消场景,取消任务时同步删除对应存储的参数
内容的提问来源于stack exchange,提问作者Eng
相关产品推荐
相关产品推荐

