如何判断我的iOS 13后台任务是否已运行?



我是第一次尝试iOS后台任务。 按照示例 WWDC'19 代码,我设置了一个简单的应用程序,该应用程序在ViewController.viewDidLoad()中将UserDefaults键的值设置为 1,并在后台任务中将其设置为 2。 我在进入背景之前和返回前景时打印了值。 该值始终打印为 1,即使让应用在后台放置一夜也是如此。我的后台任务未运行吗? 或者可能是我的UserDefaults值在前台和后台任务之间没有同步,如几个堆栈溢出问题中所讨论的那样?还是我做错了什么? 任何指针都值得赞赏。

我已经检查了"签名和功能"下的"后台模式"中的"后台获取"项,并且我还在Info.plist中的"允许的后台任务计划程序"下将"com.example.BGTask.refresh"添加为"第0项"。我正在设备上运行该应用程序,并连接到Xcode。

iOS 13.5.1, Xcode 11.5

应用委托.swift

import UIKit
import BackgroundTasks
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.BGTask.refresh", using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
return true
}
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "com.example.BGTask.refresh")
request.earliestBeginDate = Date(timeIntervalSinceNow: 15*60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: (error)")
}
}
func handleAppRefresh(task: BGAppRefreshTask) {
scheduleAppRefresh()
task.expirationHandler = {
task.setTaskCompleted(success: false)
}
UserDefaults.standard.set(2, forKey: "bgtask")
task.setTaskCompleted(success: true)
}

// MARK: UISceneSession Lifecycle
// rest of templated AppDelegate.swift

SceneDelegate.swift:在本教程之后,我在SceneDelegate中调用scheduleAppRefresh()而不是AppDelegate,并修改了这两个函数:

func sceneDidBecomeActive(_ scene: UIScene) {
print("didBecomeActive: ", UserDefaults.standard.integer(forKey: "bgtask"))
}
func sceneDidEnterBackground(_ scene: UIScene) {
print("didEnterBackground: ", UserDefaults.standard.integer(forKey: "bgtask"))
(UIApplication.shared.delegate as! AppDelegate).scheduleAppRefresh()
}

最后,在ViewController.swift

class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
UserDefaults.standard.set(1, forKey: "bgtask")
print("viewDidLoad: ", UserDefaults.standard.integer(forKey: "bgtask"))
}
}

这是我在Xcode控制台上打印出来的:

viewDidLoad:  1
didBecomeActive:  1
// tap the Home button
didEnterBackground:  1
// after a suitably long time, tap the app icon
didBecomeActive:  1

为什么UserDefaults.shared.integer(forKey: "bgtask")没有递增第二个didBecomeActive

在我看完 wwdc2019 之后

https://developer.apple.com/videos/play/wwdc2019/707/

仅当系统决定这样做时,才会执行任务

您也可以查看此论坛讨论链接:

https://forums.developer.apple.com/thread/124320

好吧,我让后台处理工作。 Xcode 控制台输出:

viewDidLoad:  1
didBecomeActive:  1
didEnterBackground:  1
didBecomeActive:  1
didEnterBackground:  1
// after about 15 minutes
didBecomeActive:  2
didEnterBackground:  2
// after staying in background overnight (~8 hours)
didBecomeActive:  19
didEnterBackground:  19

我没有勾选"后台获取",而是在"签名和功能"下的"后台模式"中勾选了"后台处理"。

应用委托.swift:

import UIKit
import BackgroundTasks
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.BGTask.refresh", using: nil) { task in
self.handleAppRefresh(task: task as! BGProcessingTask)
}
return true
}
func scheduleAppRefresh() {
let request = BGProcessingTaskRequest(identifier: "com.example.BGTask.refresh")
request.requiresNetworkConnectivity = false
request.requiresExternalPower = false
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: (error)")
}
}
func handleAppRefresh(task: BGProcessingTask) {
scheduleAppRefresh()

task.expirationHandler = {
task.setTaskCompleted(success: false)
}

// increment instead of a fixed number
UserDefaults.standard.set(UserDefaults.standard.integer(forKey: "bgtask")+1, forKey: "bgtask")
task.setTaskCompleted(success: true)
}

// MARK: UISceneSession Lifecycle
// rest of templated AppDelegate.swift

并且没有对其他文件进行其他更改。

现在,为什么BGProcessing可以工作,而BGAppRefresh却不能呢?

最新更新