Skip to content

Instantly share code, notes, and snippets.

@Mcrich23
Created April 12, 2026 21:46
Show Gist options
  • Select an option

  • Save Mcrich23/fb3e6c53cac8f256ff5adbf550038717 to your computer and use it in GitHub Desktop.

Select an option

Save Mcrich23/fb3e6c53cac8f256ff5adbf550038717 to your computer and use it in GitHub Desktop.
My best attempt to track when SwiftData/CoreData is syncing with CloudKit
import SwiftUI
import CoreData
/// A modifier that leverages several notifications to tell a bound variable if CoreData is syncing with CloudKit.
private struct CoreDataIsSyncingModifier: ViewModifier {
/// Tracks if `NSPersistentCloudKitContainer.eventChangedNotification` has pushed a import ended notification.
///
/// This is useful for when `NSPersistentStoreRemoteChange` is being tracked.
@State private var hasImported: Bool = false
/// The externally exposed boolean variable describing how the sync state.
@Binding var isSyncing: Bool
func body(content: Content) -> some View {
content
.onReceive(NotificationCenter.default.publisher(for: .NSPersistentStoreRemoteChange).receive(on: DispatchQueue.main)) { _ in
if !hasImported {
isSyncing = true
}
}
.onReceive(NotificationCenter.default.publisher(
for: NSPersistentCloudKitContainer.eventChangedNotification
).receive(on: DispatchQueue.main)) { notification in
guard let event = notification.userInfo?[NSPersistentCloudKitContainer.eventNotificationUserInfoKey]
as? NSPersistentCloudKitContainer.Event else {
return
}
switch event.type {
case .setup:
print("CloudKit setup started")
case .import:
if event.endDate == nil {
print("CloudKit Import (download) started")
isSyncing = true
} else {
print("CloudKit Import (download) ended")
isSyncing = false
hasImported = true
}
case .export:
if event.endDate == nil {
print("CloudKit Export (upload) started")
} else {
print("CloudKit Export (upload) ended")
}
@unknown default:
break
}
}
}
}
extension View {
/// A modifier that leverages several notifications to tell a bound variable if CoreData is syncing with CloudKit.
public func isCoreDataSyncing(_ isSyncing: Binding<Bool>) -> some View {
modifier(CoreDataIsSyncingModifier(isSyncing: isSyncing))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment