05/02 Phase C

This commit is contained in:
Nguyen Ngo
2026-05-03 08:31:25 -04:00
parent 8bdcbecd73
commit 59e698b5f7
6 changed files with 451 additions and 147 deletions
+53 -4
View File
@@ -1,17 +1,21 @@
// JanitorialQC.swift
// JQCApp.swift
// ------------
// App entry point. Phase B adds LocalInspection, LocalIssue,
// PendingPhoto, and SyncQueueEntry to the SwiftData model container.
// App entry point. Phase C adds BGTaskScheduler for background sync.
import SwiftUI
import SwiftData
import BackgroundTasks
@main
struct JanitorialQC: App {
struct JanitorialQCApp: App {
@StateObject private var auth = AuthManager.shared
@StateObject private var sync = SyncManager.shared
init() {
registerBackgroundTasks()
}
var body: some Scene {
WindowGroup {
ContentView()
@@ -44,4 +48,49 @@ struct JanitorialQC: App {
}
}
}
// Background Tasks
/// Register the background sync task with the OS.
/// The identifier must match BGTaskSchedulerPermittedIdentifiers in Info.plist.
private func registerBackgroundTasks() {
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.jqc.sync",
using: nil
) { task in
guard let processingTask = task as? BGProcessingTask else {
task.setTaskCompleted(success: false)
return
}
handleBackgroundSync(task: processingTask)
}
}
private func handleBackgroundSync(task: BGProcessingTask) {
// Schedule the next background run immediately
scheduleBackgroundSync()
let syncTask = Task {
await SyncManager.shared.triggerSync()
}
// If the OS needs to cancel early, cancel our work
task.expirationHandler = {
syncTask.cancel()
}
Task {
await syncTask.value
task.setTaskCompleted(success: !syncTask.isCancelled)
}
}
}
/// Schedule a background processing task.
/// Call this from sceneDidEnterBackground or after each foreground sync.
func scheduleBackgroundSync() {
let request = BGProcessingTaskRequest(identifier: "com.jqc.sync")
request.requiresNetworkConnectivity = true
request.requiresExternalPower = false
try? BGTaskScheduler.shared.submit(request)
}