mirror of
https://github.com/yattee/yattee.git
synced 2026-07-19 22:02:10 +00:00
Persist SwiftData within a background task on suspension (0xdead10cc)
On backgrounding, the app flushed pending CloudKit changes in an unguarded Task while SwiftData autosave could leave an open SQLite transaction. iOS terminates apps that hold the database lock across suspension (0xdead10cc), which was the largest crash group on build 261. On iOS, commit pending changes synchronously to release the lock, and run the async flush inside a beginBackgroundTask assertion that ends when the flush completes. Fixes 0xdead10cc SIGKILLs seen in TestFlight build 261 (17 reports).
This commit is contained in:
@@ -306,14 +306,38 @@ struct YatteeApp: App {
|
||||
// Flush pending CloudKit changes when entering background
|
||||
if newPhase == .background {
|
||||
appEnvironment.cloudKitSync.stopForegroundPolling()
|
||||
Task {
|
||||
await appEnvironment.cloudKitSync.flushPendingChanges()
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
// Persist pending SwiftData changes and run the CloudKit flush
|
||||
// inside a background-task assertion. iOS terminates apps with
|
||||
// 0xdead10cc when they hold the SwiftData/SQLite database lock
|
||||
// across suspension; committing now releases the lock, and the
|
||||
// assertion keeps the app alive until the async flush finishes.
|
||||
var backgroundTask: UIBackgroundTaskIdentifier = .invalid
|
||||
backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "PersistOnBackground") {
|
||||
if backgroundTask != .invalid {
|
||||
UIApplication.shared.endBackgroundTask(backgroundTask)
|
||||
backgroundTask = .invalid
|
||||
}
|
||||
}
|
||||
// Commit any pending changes synchronously so no open SQLite
|
||||
// transaction is left behind at suspension.
|
||||
appEnvironment.dataManager.save()
|
||||
Task {
|
||||
await appEnvironment.cloudKitSync.flushPendingChanges()
|
||||
if backgroundTask != .invalid {
|
||||
UIApplication.shared.endBackgroundTask(backgroundTask)
|
||||
backgroundTask = .invalid
|
||||
}
|
||||
}
|
||||
|
||||
if appEnvironment.settingsManager.backgroundNotificationsEnabled {
|
||||
appEnvironment.backgroundRefreshManager.scheduleIOSBackgroundRefresh()
|
||||
}
|
||||
#else
|
||||
Task {
|
||||
await appEnvironment.cloudKitSync.flushPendingChanges()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user