Blu*_*rXD 6 ios swift background-task swiftui
我正在尝试设置一些BackgroundTasks
在应用程序关闭时定期运行一些代码(比如每天一次)。我相信BackgroundTasks
swift 上的 API 就是为了这个?(如果我弄错了,请告诉我)。我按照Apple 文档上的文章来实现它,并调整它以适应 SwiftUI。
问题:后台任务永远不会触发,但处于“待处理”状态(如图所示)
免责声明:我确实添加了该Background Modes
功能并进行了检查Background fetch
,Background processing
并将标识符添加到Info.plist
代码:
Main
- 设置应用程序委托,获取场景,设置 UserDefaults 计数器,获取所有待处理任务的按钮,显示 UserDefault 计数器的文本,添加到 UserDefault 计数器的按钮,schedule()
当应用程序进入后台时调用任务
import SwiftUI
import BackgroundTasks
@main
struct GyfterApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@Environment(\.scenePhase) var scene
@AppStorage("test") var test = 1
var body: some Scene {
WindowGroup {
VStack {
Button("Test") {
BGTaskScheduler.shared.getPendingTaskRequests { all in
print("Pending Tasks Requests", all)
}
}
Text("\(test)")
Button("ADD") {
test = test + 1
}
}
.onChange(of: scene) { newValue in
switch newValue {
case .background:
print("Entered Background")
appDelegate.schedule()
default:
break
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Operation
- 操作BackgroundTasks
,它打印一条消息并向 UserDefaults 计数器加 1
class OP: Operation {
@AppStorage("test") var test = 1
override func main() {
print("OPERATION RAN")
test = test + 1
}
}
Run Code Online (Sandbox Code Playgroud)
AppDelegate
-
handleSchedule(task:)
)schedule()
仅在应用程序进入后台时调用,而不是在handleSchedule(task:)
应该触发时永远不会调用)schedule()
、创建OperationQueue
、创建Operation
、设置expirationHandler
和setTaskCompleted
添加操作到队列class AppDelegate: NSObject, UIApplicationDelegate {
@AppStorage("test") var test = 1
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("LAUNCHED")
let a = BGTaskScheduler.shared.register(forTaskWithIdentifier: "IDENTIFIER", using: nil) { task in
print("REGISTERED")
self.test = self.test + 1
self.handleSchedule(task: task as! BGAppRefreshTask)
}
print(a)
return true
}
func schedule() {
let request = BGAppRefreshTaskRequest(identifier: "IDENTIFIER")
request.earliestBeginDate = Date(timeIntervalSinceNow: 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
func handleSchedule(task: BGAppRefreshTask) {
print("HANDLING SCHEDULE")
schedule()
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
let operation = OP()
task.expirationHandler = {
print("BG Task Expired")
queue.cancelAllOperations()
}
operation.completionBlock = {
print("OPERATION COMPLETED")
task.setTaskCompleted(success: !operation.isCancelled)
}
queue.addOperation(operation)
}
}
Run Code Online (Sandbox Code Playgroud)
控制台日志:显示函数调用的打印语句
BGTaskScheduler
据称)使用标识符“注册”任务schedule()
调用)LAUNCHED
true
Pending Tasks Requests []
Entered Background
Pending Tasks Requests [<BGAppRefreshTaskRequest: INDENTIFIER, earliestBeginDate: 2022-02-28 02:57:50 +0000>]
Run Code Online (Sandbox Code Playgroud)
我将首先通过强制后台任务在设备上运行来调试它,以便您知道它是否成功:
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"IDENTIFIER"]
然而,我的预感是,当您离开范围时,您的操作队列只是被释放,因为它没有连接到任何东西。可能您需要waitUntilAllOperationsAreFinished()
确保此代码不会通过排队操作退出作用域。
归档时间: |
|
查看次数: |
1103 次 |
最近记录: |