Fix CloudSyncManager sync status getting stuck on 'Syncing...'

- Set initial sync status on init based on iCloud availability
- Update status after initial synchronize call in init
- Properly set isSyncing and syncStatus in scheduleDelayedCloudCheck
- Update syncStatus to 'Synced' after handling cloud changes
This commit is contained in:
Matt Bruce 2026-01-04 13:28:20 -06:00
parent b5a5c62fa8
commit 8add0a801a

View File

@ -153,6 +153,15 @@ public final class CloudSyncManager<T: PersistableData> {
UserDefaults.standard.set(true, forKey: iCloudEnabledKey) UserDefaults.standard.set(true, forKey: iCloudEnabledKey)
} }
// Set initial sync status
if !iCloudAvailable {
syncStatus = "iCloud unavailable"
} else if !iCloudEnabled {
syncStatus = "Sync disabled"
} else {
syncStatus = "Ready"
}
// Register for iCloud changes // Register for iCloud changes
if iCloudAvailable, let store = iCloudStore { if iCloudAvailable, let store = iCloudStore {
NotificationCenter.default.addObserver( NotificationCenter.default.addObserver(
@ -173,6 +182,8 @@ public final class CloudSyncManager<T: PersistableData> {
// Trigger iCloud sync // Trigger iCloud sync
if iCloudEnabled { if iCloudEnabled {
store.synchronize() store.synchronize()
lastSyncDate = Date()
syncStatus = "Synced"
} }
} }
@ -337,11 +348,15 @@ public final class CloudSyncManager<T: PersistableData> {
private func scheduleDelayedCloudCheck() { private func scheduleDelayedCloudCheck() {
Design.debugLog("CloudSyncManager[\(T.dataIdentifier)]: Scheduling delayed cloud check...") Design.debugLog("CloudSyncManager[\(T.dataIdentifier)]: Scheduling delayed cloud check...")
isSyncing = true
syncStatus = "Syncing..."
Task { @MainActor in Task { @MainActor in
try? await Task.sleep(for: .seconds(2)) try? await Task.sleep(for: .seconds(2))
guard let store = iCloudStore else { guard let store = iCloudStore else {
isSyncing = false
syncStatus = "iCloud unavailable"
hasCompletedInitialSync = true hasCompletedInitialSync = true
return return
} }
@ -364,6 +379,9 @@ public final class CloudSyncManager<T: PersistableData> {
) )
} }
isSyncing = false
lastSyncDate = Date()
syncStatus = "Synced"
hasCompletedInitialSync = true hasCompletedInitialSync = true
} }
} }
@ -375,7 +393,6 @@ public final class CloudSyncManager<T: PersistableData> {
case NSUbiquitousKeyValueStoreServerChange, case NSUbiquitousKeyValueStoreServerChange,
NSUbiquitousKeyValueStoreInitialSyncChange: NSUbiquitousKeyValueStoreInitialSyncChange:
Design.debugLog("CloudSyncManager[\(T.dataIdentifier)]: Data changed from another device") Design.debugLog("CloudSyncManager[\(T.dataIdentifier)]: Data changed from another device")
syncStatus = "Received update"
if let cloudData = loadCloud(), cloudData.syncPriority > data.syncPriority { if let cloudData = loadCloud(), cloudData.syncPriority > data.syncPriority {
data = cloudData data = cloudData
@ -392,6 +409,9 @@ public final class CloudSyncManager<T: PersistableData> {
) )
} }
lastSyncDate = Date()
syncStatus = "Synced"
case NSUbiquitousKeyValueStoreQuotaViolationChange: case NSUbiquitousKeyValueStoreQuotaViolationChange:
Design.debugLog("CloudSyncManager[\(T.dataIdentifier)]: iCloud quota exceeded") Design.debugLog("CloudSyncManager[\(T.dataIdentifier)]: iCloud quota exceeded")
syncStatus = "Storage full" syncStatus = "Storage full"