我正在使用新的 iOS13 后台任务框架,并实现 BGAppRefreshTask 类型。我的问题是,即使在等待几个小时之后,我的设备也永远不会调用该任务,但我能够使用调用 _simulateLaunchForTaskWithIdentifier 的调试器技巧成功运行代码。
我已设置以下内容:
- 使用后台模式功能启用我的应用程序,检查“后台获取”。
- 将我的背景 ID 添加到 Info.plist 的“允许的后台任务调度程序标识符”下:“com.XYZ.PearWeather.backgroundAlerts”。
我已在我的 AppDelegate 中注册了来自 application(didFinishLaunchingWithOptions) 的任务:
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.XYZ.PearWeather.backgroundAlerts", using: nil) { task in
self.backgroundAlerts(task: task as! BGAppRefreshTask)
}
我正在 AppDelegate 内的 func 中安排任务,并从我的 SceneDelegate sceneDidEnterBackground() 调用它。它本来是一个静态函数,但我现在将其更改为实例函数,并获取 AppDelegate 实例(因为我在绝望中尝试了很多更改):
func sceneDidEnterBackground(_ scene: UIScene) {
(UIApplication.shared.delegate as! AppDelegate).scheduleBackgroundAlerts()
}
func scheduleBackgroundAlerts() {
let request = BGAppRefreshTaskRequest(identifier: "com.XYZ.PearWeather.backgroundAlerts")
request.earliestBeginDate = Date(timeIntervalSinceNow: 5 * 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
至少在Debugger场景下,提交调用没有错误。我已经为上面的 timeIntervalSinceNow 参数尝试了许多不同的值。我还从任务处理程序本身调用此 ScheduleBackgroundAlerts() 函数,如下所示:
func backgroundAlerts(task: BGAppRefreshTask) {
scheduleBackgroundAlerts()
task.expirationHandler = {
// After all operations are cancelled, the completion block below is called to set the task to complete.
task.setTaskCompleted(success: false)
}
AlertsOperation.showNotification()
task.setTaskCompleted(success: true)
}
这个实现发生了很大的变化 - 我最初使用了一个OperationQueue,尝试将scheduleBackgroundAlerts()调用放在func的开头和结尾,等等。现在它被剥离了。 AlertOperation.showNotification() 现在也非常简单:
static func showNotification() {
let now = Date()
let bg = Locale.currentLocale().formattedTime(date: now)
SettingsManager.shared.settings.bg = bg
}
这只是在 UserDefaults 中存储一个值(在我的 SettingsManager 中,其详细信息与此处无关),我可以在我的应用程序中读回该值以查看是否发生了任何情况。
现在,该函数的原始实现使用 UNUserNotificationCenter 等发出本地通知,这就是我在此后台任务中尝试执行的操作。这在调试器中工作得很好,但我将其简化为这个简单的代码,只是为了制作一个非常小的实现。
正如我所说,从调试器调用任务处理程序可以正常工作,使用:
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.XYZ.PearWeather.backgroundAlerts"]
但设备本身没有发生任何事情。我看不到我错过了什么。我也不知道如何从后台任务处理程序中记录任何异常。
我是 Swift 和 iOS 的新手,所以非常感谢您的指点。上面的大部分代码几乎都是关于这个主题的许多教程的副本。但对我来说,一切都行不通,我已经没有选择了!