From d957921fe3e4f1a17afa00e37ab9786ff69b781a Mon Sep 17 00:00:00 2001 From: alexandrev-tibco Date: Fri, 24 Jul 2026 15:47:46 +0200 Subject: [PATCH] =?UTF-8?q?2.0:=20sync=20CloudKit=20en=20tiempo=20real=20v?= =?UTF-8?q?=C3=ADa=20push=20silencioso?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NSPersistentCloudKitContainer solo sincronizaba de forma oportunista (sin push), por lo que un plato nuevo tardaba mucho o no aparecía en el otro dispositivo. Se activa el push de CloudKit: - aps-environment en MealMood.entitlements vía variable APS_ENVIRONMENT (development en Debug, production en Release) para no romper TestFlight. - AppDelegate con registerForRemoteNotifications() + manejo del push silencioso; el mirror de SwiftData importa al ser despertado. - (Capability Push Notifications habilitada en el App ID por API.) Pendiente: regenerar el provisioning profile AppStore con Push antes de la build 63, y validar el sync push en iPhone+iPad vía TestFlight. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01A3HaWmmtTQ1vdTERtSYU6p --- MealMood.xcodeproj/project.pbxproj | 2 ++ MealMood/MealMoodApp.swift | 23 +++++++++++++++++++++++ MealMood/Resources/MealMood.entitlements | 2 ++ 3 files changed, 27 insertions(+) diff --git a/MealMood.xcodeproj/project.pbxproj b/MealMood.xcodeproj/project.pbxproj index 73c1575..bec32b9 100644 --- a/MealMood.xcodeproj/project.pbxproj +++ b/MealMood.xcodeproj/project.pbxproj @@ -923,6 +923,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = MealMood/Resources/MealMood.entitlements; + APS_ENVIRONMENT = production; CODE_SIGN_IDENTITY = "iPhone Developer"; CURRENT_PROJECT_VERSION = 62; DEVELOPMENT_TEAM = 2825Q76T7H; @@ -1028,6 +1029,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = MealMood/Resources/MealMood.entitlements; + APS_ENVIRONMENT = development; CODE_SIGN_IDENTITY = "iPhone Developer"; CURRENT_PROJECT_VERSION = 62; DEVELOPMENT_TEAM = 2825Q76T7H; diff --git a/MealMood/MealMoodApp.swift b/MealMood/MealMoodApp.swift index 90056ea..3912143 100644 --- a/MealMood/MealMoodApp.swift +++ b/MealMood/MealMoodApp.swift @@ -1,11 +1,32 @@ import SwiftUI import SwiftData +import UIKit import FirebaseCore import FirebaseCrashlytics #if canImport(GoogleMobileAds) import GoogleMobileAds #endif +/// Registers for remote notifications so CloudKit (the NSPersistentCloudKitContainer +/// behind SwiftData) receives its silent-push subscriptions and imports changes +/// in near-real-time across devices. Silent pushes are coalesced by the system, +/// so battery cost is negligible — no polling. +final class AppDelegate: NSObject, UIApplicationDelegate { + func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { + application.registerForRemoteNotifications() + return true + } + + func application(_ application: UIApplication, + didReceiveRemoteNotification userInfo: [AnyHashable: Any], + fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { + // CloudKit silent push: SwiftData's mirror imports on its own once woken; + // report new data so the system keeps delivering sync pushes. + completionHandler(.newData) + } +} + /// Whether the store is syncing through CloudKit this launch. When true, the /// legacy iCloud KV snapshot sync must stay inert (both would fight). enum CloudSyncRuntime { @@ -16,6 +37,8 @@ enum CloudSyncRuntime { @main struct MealMoodApp: App { + @UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate + private let modelContainer: ModelContainer = { let schema = Schema([ AppSettings.self, diff --git a/MealMood/Resources/MealMood.entitlements b/MealMood/Resources/MealMood.entitlements index 16399fa..e6b301f 100644 --- a/MealMood/Resources/MealMood.entitlements +++ b/MealMood/Resources/MealMood.entitlements @@ -2,6 +2,8 @@ + aps-environment + $(APS_ENVIRONMENT) com.apple.developer.icloud-container-identifiers iCloud.com.alexandrev.mealmood