mirror of
https://github.com/yattee/yattee.git
synced 2026-10-23 05:02:53 +00:00
Stop the progress save from getting the app killed at suspension
17 of the build 270 crash logs are 0xdead10cc kills on the main thread inside DataManager.save(), every one reached from the 5-second PlayerService progress-save timer. During background audio the timer keeps writing; when playback stops the app can be suspended mid-save, still holding the SQLite lock in the shared app-group container. Wrap the periodic save in a background-task assertion when the app is not active, and skip the write when the position has not moved since the last save, so a paused player stops writing every five seconds. The remaining six 0xdead10cc logs die in DataManager.init recovering the WAL during a background launch. They are most likely the aftermath of these dirty kills, so store opening is left as is.
This commit is contained in:
@@ -131,6 +131,8 @@ final class PlayerService {
|
||||
|
||||
private var progressSaveTimer: Timer?
|
||||
private let progressSaveInterval: TimeInterval = 5
|
||||
/// Last position written by the periodic progress save.
|
||||
private var lastSavedProgress: (videoID: String, seconds: TimeInterval)?
|
||||
|
||||
/// Now Playing service for Control Center/Lock Screen.
|
||||
private let nowPlayingService = NowPlayingService()
|
||||
@@ -2781,8 +2783,30 @@ final class PlayerService {
|
||||
guard let video = state.currentVideo,
|
||||
state.currentTime > 0 else { return }
|
||||
|
||||
// A paused player keeps the timer running; rewriting the same position
|
||||
// only adds database writes, including while the app is being suspended.
|
||||
let position = (videoID: video.id.videoID, seconds: state.currentTime)
|
||||
guard lastSavedProgress?.videoID != position.videoID
|
||||
|| lastSavedProgress?.seconds != position.seconds else { return }
|
||||
lastSavedProgress = position
|
||||
|
||||
// Save locally only during playback - no iCloud sync overhead.
|
||||
// Live streams still get a history entry, but no resume position.
|
||||
#if os(iOS)
|
||||
// In the background (audio playback) the app can be suspended the
|
||||
// moment playback stops. Suspending mid-save holds the SQLite lock in
|
||||
// the shared app-group container and iOS kills the app with
|
||||
// 0xdead10cc, so keep it running until the save has committed.
|
||||
var backgroundTask: UIBackgroundTaskIdentifier = .invalid
|
||||
if UIApplication.shared.applicationState != .active {
|
||||
backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "SaveWatchProgress")
|
||||
}
|
||||
defer {
|
||||
if backgroundTask != .invalid {
|
||||
UIApplication.shared.endBackgroundTask(backgroundTask)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
dataManager.updateWatchProgressLocal(for: video, seconds: state.currentTime, duration: state.duration, isLive: state.isLive)
|
||||
watchHistorySyncService?.recordProgress(videoID: video.id.videoID)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user