feat(sync): add pagination, cancellation, and network restoration
- CloudKit pagination: fetchAllRecords() handles >400 record batches with cursor-based pagination (400 records per page) - Cancellation support: SyncCancellationToken protocol enables graceful sync termination when background tasks expire - Per-entity progress: SyncState now tracks timestamps per entity type so interrupted syncs resume where they left off - NetworkMonitor: NWPathMonitor integration triggers sync on network restoration with 2.5s debounce to handle WiFi↔cellular flapping - wasCancelled flag in SyncResult distinguishes partial from full syncs This addresses critical data sync issues: - CloudKit queries were limited to ~400 records but bundled data has ~5000 games - Background tasks could be killed mid-sync without saving progress - App had no awareness of network state changes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -152,13 +152,19 @@ struct BootstrappedContentView: View {
|
||||
await StoreManager.shared.loadProducts()
|
||||
await StoreManager.shared.updateEntitlements()
|
||||
|
||||
// 6. App is now usable
|
||||
// 6. Start network monitoring and wire up sync callback
|
||||
NetworkMonitor.shared.onSyncNeeded = {
|
||||
await BackgroundSyncManager.shared.triggerSyncFromNetworkRestoration()
|
||||
}
|
||||
NetworkMonitor.shared.startMonitoring()
|
||||
|
||||
// 7. App is now usable
|
||||
isBootstrapping = false
|
||||
|
||||
// 7. Schedule background tasks for future syncs
|
||||
// 8. Schedule background tasks for future syncs
|
||||
BackgroundSyncManager.shared.scheduleAllTasks()
|
||||
|
||||
// 8. Background: Try to refresh from CloudKit (non-blocking)
|
||||
// 9. Background: Try to refresh from CloudKit (non-blocking)
|
||||
Task.detached(priority: .background) {
|
||||
await self.performBackgroundSync(context: context)
|
||||
await MainActor.run {
|
||||
|
||||
Reference in New Issue
Block a user