我一直得到错误
No task request with identifier <decode: missing data> has been scheduled
在我的调试器输出中,所以我决定尝试运行苹果提供的示例代码,并得到相同的错误。我已经尝试了多个计算机和Xcode版本,来自不同来源的多个示例项目,没有任何工作。
我的AppDelegate.swift文件:
import UIKit
import Firebase
import BackgroundTasks
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
BGTaskScheduler.shared.register(forTaskWithIdentifier: “redacted.identifier”, using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
BGTaskScheduler.shared.cancelAllTaskRequests()
scheduleAppRefresh()
}
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "redacted.identifier")
request.earliestBeginDate = Date(timeIntervalSinceNow: 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: (error)")
}
}
func handleAppRefresh(task: BGAppRefreshTask) {
scheduleAppRefresh()
let db = Firestore.firestore()
db.collection("devices").document(UIDevice.current.identifierForVendor!.uuidString).setData([
"batteryLevel": UIDevice.current.batteryLevel*100
]) { err in
if let err = err {
print("Error writing document: (err)")
} else {
print("success")
task.setTaskCompleted(success: true)
}
}
task.expirationHandler = {
task.setTaskCompleted(success: false)
}
}
我正在运行
测试后台取回e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"redacted.identifier"]
在Xcode控制台中,之后出现上述错误。
控制台输出:
Simulating launch for task with identifier redacted.identifier
No task request with identifier <decode: missing data> has been scheduled
几个潜在的问题:
-
在模拟器上测试时会发生这种情况。使用物理设备
-
确保您的
Info.plist
有一个"允许的后台任务调度程序标识符"(即BGTaskSchedulerPermittedIdentifiers
)条目与您的后台任务的标识符。 -
确保在
BGTaskScheduler.shared.submit(...)
行之后立即设置断点,并且在调用submit
之后执行_simulateLaunchForTaskWithIdentifier
。例如,确保您甚至到达submit
调用。(见下一点) -
值得注意的是,苹果的例子(和你的例子)在
applicationDidEnterBackground(_:)
中调度它。但是如果你使用的是UIWindowSceneDelegate
(即在你的SceneDelegate
中),那么应用程序委托的applicationDidEnterBackground(_:)
不会被调用,而是场景委托的sceneDidEnterBackground(_:)
被调用。我把BGAppRefreshTaskRequest
的调度放在场景委托的sceneDidEnterBackground(_:)
中。
我在设备上测试时也遇到了同样的问题。转到设备设置>一般比;后台应用刷新并打开后台应用刷新。
还有一种情况没有在其他答案中提到,如果您试图提交不同或多个刷新任务,您可能会遇到下面的错误情况。问题是,目前提到的错误没有在Xcode 13.1中抛出,所以它看起来像提交请求工作,但基本上它没有。
苹果医生:可同时安排1个刷新任务和10个处理任务。尝试调度更多任务返回BGTaskScheduler.Error.Code.tooManyPendingTaskRequests.
看起来applicationDidEnterBackground
永远不会被调用,检查一下(添加断点)
func applicationDidEnterBackground(_ application: UIApplication) { BGTaskScheduler.shared.cancelAllTaskRequests() scheduleAppRefresh() }
因为基于场景的配置生命周期
如果为真,将逻辑移到SceneDelegate类
func sceneDidEnterBackground(_ scene: UIScene) { BGTaskScheduler.shared.cancelAllTaskRequests() scheduleAppRefresh() }