Dea*_*rae 9 background task ios swift
我正在使用新的 iOS13 后台任务框架,并实现了 BGAppRefreshTask 类型。我的问题是,我的设备从不调用任务,即使等待了几个小时,但我能够使用调用 _simulateLaunchForTaskWithIdentifier 的调试器技巧成功运行代码。
我已经设置了以下内容:
我已经在我的 AppDelegate 中从 application(didFinishLaunchingWithOptions) 注册了任务:
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.XYZ.PearWeather.backgroundAlerts", using: nil) { task in
self.backgroundAlerts(task: task as! BGAppRefreshTask)
}
Run Code Online (Sandbox Code Playgroud)
我正在 AppDelegate 内的 func 中调度任务,并从我的 SceneDelegate sceneDidEnterBackground() 调用它。它原本是一个静态的func,但我现在已经把它改成了一个实例func,并得到了AppDelegate实例(因为我在绝望中尝试了很多变化):
func sceneDidEnterBackground(_ scene: UIScene) {
(UIApplication.shared.delegate as! AppDelegate).scheduleBackgroundAlerts()
}
Run Code Online (Sandbox Code Playgroud)
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)")
}
}
Run Code Online (Sandbox Code Playgroud)
至少在Debugger场景下,submit调用是没有错误的。我为上面的 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)
}
Run Code Online (Sandbox Code Playgroud)
这个实现改变了很多 - 我最初使用了一个 OperationQueue,尝试在 func 的开头和结尾放置 scheduleBackgroundAlerts() 调用,等等。现在它被剥离了。AlertOperation.showNotification() 现在也非常简单:
static func showNotification() {
let now = Date()
let bg = Locale.currentLocale().formattedTime(date: now)
SettingsManager.shared.settings.bg = bg
}
Run Code Online (Sandbox Code Playgroud)
这只是在 UserDefaults 中存储一个值(在我的 SettingsManager 中,其详细信息与此处无关),我可以在我的应用程序中读回该值以查看是否发生了任何事情。
现在,此 func 的原始实现使用 UNUserNotificationCenter 等发出本地通知,这就是我在此后台任务中尝试执行的操作。这在调试器中运行良好,但我将其简化为这个简单的代码,只是为了实现一个非常小的实现。
正如我所说,从调试器调用任务处理程序工作正常,使用:
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.XYZ.PearWeather.backgroundAlerts"]
Run Code Online (Sandbox Code Playgroud)
但是设备本身没有发生任何事情。我看不到我错过了什么。我也不知道如何从后台任务处理程序中记录任何异常。
我是 Swift 和 iOS 的新手,因此感谢您的指点。上面的大部分代码几乎是关于这个主题的许多教程的副本。然而,对我来说,事情并没有奏效,我已经没有选择了!
request(BGTaskScheduler.shared.submit(request))提交请求后和提交后运行命令后代码中有断点
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.XYZ.PearWeather.backgroundAlerts"]
Run Code Online (Sandbox Code Playgroud)
然后将为该标识符调用注册的处理程序。检查POC以了解更多详细信息。
这是我使用的。
在我的 AppDelegate 中,iOS13 代码。不包括旧式获取:
class AppDelegate: UIResponder, UIApplicationDelegate, URLSessionDelegate, UNUserNotificationCenterDelegate {
var backgroundSessionCompletionHandler: (() -> Void)?
var backgroundSynchTask: UIBackgroundTaskIdentifier = .invalid
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 13.0, *) {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.WH.Air-Compare.WayneBGrefresh", using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
self.logSB.verbose("iOS 13 Registered for Background duty")
}
} else {
// Fallback on earlier versions
self.logSB.verbose("iOS < 13 Registering for Background duty")
UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIntervalMinimum)
}
}
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler:@escaping () -> Void) {
let dateFormatter = DateFormatter() // format the date for output
dateFormatter.dateStyle = DateFormatter.Style.medium
dateFormatter.timeStyle = DateFormatter.Style.long
let convertedDate = dateFormatter.string(from: Date())
self.logSB.info("Background URLSession handled at \(convertedDate)")
self.logSB.info("Background URLSession ID \(identifier)")
let config = URLSessionConfiguration.background(withIdentifier: "WayneBGconfig")
let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
session.getTasksWithCompletionHandler { (dataTasks, uploadTasks, downloadTasks) -> Void in
// yay! you have your tasks!
self.logSB.info("Background completion handler here with \(downloadTasks.count) tasks")
for i in 0...max(0,downloadTasks.count - 1) {
let description: String = downloadTasks[i].taskDescription!
self.logSB.info("Task ID \(i) is \(description)")
}
}
backgroundSessionCompletionHandler = completionHandler
}
func applicationDidEnterBackground(_ application: UIApplication) {
if #available(iOS 13.0, *) {
scheduleAppRefresh()
} else {
// Fallback on earlier versions
}
}
@available(iOS 13.0, *)
func scheduleAppRefresh() {
logSB.info("Scheduling the AppRefresh in iOS 13 !!")
let request = BGAppRefreshTaskRequest(identifier: "com.WH.Air-Compare.WayneBGrefresh")
request.earliestBeginDate = Date(timeIntervalSinceNow: 2 * 60) // Fetch no earlier than 2 minutes from now
do {
try BGTaskScheduler.shared.submit(request)
} catch {
logSB.error("Could not schedule app refresh: \(error)")
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2212 次 |
| 最近记录: |