Add StadiumAlias CloudKit sync and offline-first data architecture
- Add CKStadiumAlias model for CloudKit record mapping - Add fetchStadiumAliases/fetchStadiumAliasChanges to CloudKitService - Add syncStadiumAliases to CanonicalSyncService for delta sync - Add subscribeToStadiumAliasUpdates for push notifications - Update cloudkit_import.py with --stadium-aliases-only option Data Architecture Updates: - Remove obsolete provider files (CanonicalDataProvider, CloudKitDataProvider, StubDataProvider) - AppDataProvider now reads exclusively from SwiftData - Add background CloudKit sync on app startup (non-blocking) - Document data architecture in CLAUDE.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -90,13 +90,48 @@ struct BootstrappedContentView: View {
|
||||
let bootstrapService = BootstrapService()
|
||||
|
||||
do {
|
||||
// 1. Bootstrap from bundled JSON if first launch (no data exists)
|
||||
try await bootstrapService.bootstrapIfNeeded(context: context)
|
||||
|
||||
// 2. Configure DataProvider with SwiftData context
|
||||
AppDataProvider.shared.configure(with: context)
|
||||
|
||||
// 3. Load data from SwiftData into memory
|
||||
await AppDataProvider.shared.loadInitialData()
|
||||
|
||||
// 4. App is now usable
|
||||
isBootstrapping = false
|
||||
|
||||
// 5. Background: Try to refresh from CloudKit (non-blocking)
|
||||
Task.detached(priority: .background) {
|
||||
await self.performBackgroundSync(context: context)
|
||||
}
|
||||
} catch {
|
||||
bootstrapError = error
|
||||
isBootstrapping = false
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func performBackgroundSync(context: ModelContext) async {
|
||||
let syncService = CanonicalSyncService()
|
||||
|
||||
do {
|
||||
let result = try await syncService.syncAll(context: context)
|
||||
|
||||
// If any data was updated, reload the DataProvider
|
||||
if !result.isEmpty {
|
||||
await AppDataProvider.shared.loadInitialData()
|
||||
print("CloudKit sync completed: \(result.totalUpdated) items updated")
|
||||
}
|
||||
} catch CanonicalSyncService.SyncError.cloudKitUnavailable {
|
||||
// Offline or CloudKit not available - silently continue with local data
|
||||
print("CloudKit unavailable, using local data")
|
||||
} catch {
|
||||
// Other sync errors - log but don't interrupt user
|
||||
print("Background sync error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Bootstrap Loading View
|
||||
|
||||
Reference in New Issue
Block a user