- Re-ran xcodegen so ButtonStyles.swift is included (fixes PrimaryButtonStyle and ScaleButtonStyle not in scope in LoginView and LANTriggerSection) - BackgroundTaskManager: access BackupEngine.shared inside @MainActor Task instead of nonisolated context - SFTPService: change var buffer → let (never mutated) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
72 lines
2.4 KiB
Swift
72 lines
2.4 KiB
Swift
import Foundation
|
|
import BackgroundTasks
|
|
|
|
final class BackgroundTaskManager {
|
|
static let backupTaskID = "com.albert.nasbackup.backup"
|
|
static let refreshTaskID = "com.albert.nasbackup.refresh"
|
|
|
|
static func registerTasks() {
|
|
BGTaskScheduler.shared.register(
|
|
forTaskWithIdentifier: backupTaskID,
|
|
using: nil
|
|
) { task in
|
|
guard let task = task as? BGProcessingTask else { return }
|
|
BackgroundTaskManager.handleBackupTask(task)
|
|
}
|
|
|
|
BGTaskScheduler.shared.register(
|
|
forTaskWithIdentifier: refreshTaskID,
|
|
using: nil
|
|
) { task in
|
|
guard let task = task as? BGAppRefreshTask else { return }
|
|
BackgroundTaskManager.handleRefreshTask(task)
|
|
}
|
|
}
|
|
|
|
static func scheduleBackup(delay: TimeInterval = 30) {
|
|
let request = BGProcessingTaskRequest(identifier: backupTaskID)
|
|
request.requiresNetworkConnectivity = true
|
|
request.requiresExternalPower = false
|
|
request.earliestBeginDate = Date(timeIntervalSinceNow: delay)
|
|
do {
|
|
try BGTaskScheduler.shared.submit(request)
|
|
} catch {
|
|
print("BGTask schedule failed: \(error)")
|
|
}
|
|
}
|
|
|
|
static func scheduleAppRefresh() {
|
|
let request = BGAppRefreshTaskRequest(identifier: refreshTaskID)
|
|
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
|
|
do {
|
|
try BGTaskScheduler.shared.submit(request)
|
|
} catch {
|
|
print("BGRefresh schedule failed: \(error)")
|
|
}
|
|
}
|
|
|
|
private static func handleBackupTask(_ task: BGProcessingTask) {
|
|
scheduleBackup()
|
|
task.expirationHandler = { Task { await BackupEngine.shared.cancel() } }
|
|
Task { @MainActor in
|
|
do {
|
|
let store = ConnectionStore.shared
|
|
guard let connection = store.savedConnection else {
|
|
task.setTaskCompleted(success: false)
|
|
return
|
|
}
|
|
let filter = store.backupFilter
|
|
_ = try await BackupEngine.shared.run(connection: connection, filter: filter, triggeredByLAN: true)
|
|
task.setTaskCompleted(success: true)
|
|
} catch {
|
|
task.setTaskCompleted(success: false)
|
|
}
|
|
}
|
|
}
|
|
|
|
private static func handleRefreshTask(_ task: BGAppRefreshTask) {
|
|
scheduleAppRefresh()
|
|
task.setTaskCompleted(success: true)
|
|
}
|
|
}
|