Enable CloudKit sync for Watch app and fix WCSession handling

- Watch now uses CloudKit for data persistence (syncs automatically with iPhone)
- Added iCloud/CloudKit entitlements to Watch app (debug and release)
- Fixed WCSession delegate to handle messages with reply handler
- Watch UI now shows "Already Rated" screen after voting
- Invalidate LiveActivityScheduler cache when mood is logged
- WCSession now used only for immediate UI updates, not data persistence

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-03 11:01:33 -06:00
parent 406d9ee4fd
commit 00cbd476d4
6 changed files with 147 additions and 66 deletions

View File

@@ -3,7 +3,8 @@
// Feels
//
// Unified data provider for Widget and Watch extensions.
// Uses App Group container with CloudKit disabled for extension safety.
// - Watch: Uses CloudKit for automatic sync with iPhone
// - Widget: Uses local App Group storage (widgets can't use CloudKit)
//
// Add this file to: FeelsWidgetExtension, Feels Watch App
//
@@ -14,7 +15,8 @@ import WidgetKit
import os.log
/// Unified data provider for Widget and Watch extensions
/// Uses its own ModelContainer with App Group storage (no CloudKit)
/// - Watch: Uses CloudKit for automatic sync with iPhone (no WCSession needed for data)
/// - Widget: Uses local App Group storage (widgets can't use CloudKit)
@MainActor
final class ExtensionDataProvider {
@@ -40,11 +42,31 @@ final class ExtensionDataProvider {
// Try to use shared app group container
do {
let storeURL = try getStoreURL()
#if os(watchOS)
// Watch uses CloudKit for automatic sync with iPhone
let cloudKitContainerID: String
#if DEBUG
cloudKitContainerID = "iCloud.com.tt.feelsDebug"
#else
cloudKitContainerID = "iCloud.com.tt.feels"
#endif
let configuration = ModelConfiguration(
schema: schema,
url: storeURL,
cloudKitDatabase: .none // Extensions don't sync directly
cloudKitDatabase: .private(cloudKitContainerID)
)
Self.logger.info("Watch using CloudKit container: \(cloudKitContainerID)")
#else
// Widget uses local storage only (can't use CloudKit)
let configuration = ModelConfiguration(
schema: schema,
url: storeURL,
cloudKitDatabase: .none
)
#endif
return try ModelContainer(for: schema, configurations: [configuration])
} catch {
Self.logger.warning("Falling back to in-memory storage: \(error.localizedDescription)")