2.0: sync CloudKit en tiempo real vía push silencioso
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) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A3HaWmmtTQ1vdTERtSYU6p
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>$(APS_ENVIRONMENT)</string>
|
||||
<key>com.apple.developer.icloud-container-identifiers</key>
|
||||
<array>
|
||||
<string>iCloud.com.alexandrev.mealmood</string>
|
||||
|
||||
Reference in New Issue
Block a user