Learn how to integrate your app with iCloud for effective data storage.

Documentation

Posts under iCloud subtopic

Post

Replies

Boosts

Views

Activity

Has anyone successfully used NSStagedMigrationManager?
I've been trying to build an example of NSStagedMigrationManager from some Core Data migration tests to replace a custom migration manager solution I'd constructed, without much success. The Core Data model has seven model versions. Most support lightweight migration, but two of the migrations in the middle of the sequence used NSMappingModel. In the first beta, just attempting to construct an NSStagedMigrationManager from the series of stages failed with an unrecognized selector. That no longer happens in b4, but I now get an error that "Duplicate version checksums across stages detected." If I restrict myself to just the first three versions of the model (that only require lightweight migration), I can build the migration manager. But if I attempt to use it to migrate a persistent store, it fails somewhere in NSPersistentStoreCoordinator with a nilError. The documentation is almost nonexistent for this process, and the WWDC session that introduced it isn't much more than a breezy overview. So maybe I'm holding it wrong? (And, yes: FB12339663)
7
0
2.4k
Mar ’26
How to switch between Core Data Persistent Stores?
What is the best way to switch between Core Data Persistent Stores? My use case is that I have a multi-user app that stores thousands of data items unique to each user. To me, having Persistent Stores for each user seems like the best design to keep their data separate and private. (If anyone believes that storing the data for all users in one Persistent Store is a better design, I'd appreciate hearing from them.) Customers might switch users 5 to 10 times a day. Switching users must be fast, say a second or two at most.
1
0
148
Jun ’25
Cannot create new CloudKit container after deleting all containers - need help
I accidentally deleted all CloudKit containers from the CloudKit Database console, and now I'm unable to create new containers. Both the CloudKit Console website and Xcode are not allowing me to create any new containers. Is there a way to restore the deleted containers? How can I create a new CloudKit container if the console website is not responding? Thank you.
2
0
235
Mar ’26
Orphaning a CKAsset
I'm running into a problem in my attempt to clear CKAssets on the iCloud server. The documentation for CKAsset says: If you no longer require an asset that’s on the server, you don’t delete it. Instead, orphan the asset by setting any fields that contain the asset to nil and then saving the record. CloudKit periodically deletes orphaned assets from the server. I'm deleting image file assets which are properties on an ImageReference type (largeImage and thumbNailImage properties). When I delete an image, I am setting those properties to nil and sending the record for the ImageReference to iCloud using the async CKDatabase.modifyRecords method. This always results in an error: <CKError 0x600000d92a60: "Asset File Not Found" (16/3002); "open error: 2 (No such file or directory)"> And of course the assets still appear in the CloudKit dashboard. What is the proper way of orphaning the assets on the CloudKit server?
4
0
487
Mar ’26
SwiftData Class Inheritance
Hi, I'm considering using the new SwiftData class inheritance for a new app I'm building. I have a few questions: Is it working well enough for production? I have a number of different object types in my app. Some of them are very similar, and there's always a balance to be struck when it comes to splitting them into different types using class inheritance. Are there some good advice on when to use multiple classes instead of squeezing my object types into a single class? Is there advice against using class inheritance in multiple levels (3-4)? Claes
1
0
155
Jul ’25
CloudKit: Efficient way to get user's rank in leaderboard without fetching all records?
CloudKit: Efficient way to get user's rank in leaderboard without fetching all records? I'm building a leaderboard feature using CloudKit's public database and need advice on the best approach to calculate a user's rank efficiently. Current Setup Record Structure: Record Type: LeaderboardScore Fields: period (String): "daily", "weekly", "monthly", "allTime" score (Int): User's score profile (Reference): Link to user's profile achievedAt (Date): Timestamp Leaderboard Display: Initially fetch first 15 users (sorted by score descending) Paginate to load more as user scrolls Show total player count Show current user's rank (even if not in top 15) The Challenge I can fetch the first 15 users easily with a sorted query, but I need to display the current user's rank regardless of their position. For example: User could be ranked #1 (in top 15) ✅ Easy User could be ranked #247 (not in top 15) ❌ How to get this efficiently? My Current Approach Query records with scores higher than the user's score and count them: // Count how many users scored higher let predicate = NSPredicate( format: "period == %@ AND score > %d", period, userScore ) // Rank = count + 1 Concerns For 1000+ users with better scores, this requires multiple paginated queries Even with desiredKeys: [], I'm concerned about performance and CloudKit request limits Questions Is there a CloudKit API I'm missing that can efficiently count records matching a predicate without fetching all the records and paginating? Is this approach acceptable for a leaderboard with 1K-10K users? Does fetching with desiredKeys: [] help significantly with performance? Are there any optimizations I should consider to make this more efficient? What's the recommended approach for calculating user rank in CloudKit at this scale? Current Scale Expected: 1,000-10,000 active users per leaderboard period Platform: iOS 17+, SwiftUI Any guidance on best practices for leaderboards usecase in CloudKit would be greatly appreciated!
3
0
270
Mar ’26
SwiftData ModelContext Pollution with Multiple ModelContainers and Schemas
I have two different VersionedSchema accessed via two different and distinct in-memory ModelContainers. However, both schemas have a model named Item. LocalSchema.Item and RemoteSchema.Item have slightly different properties. If I create and save RemoteSchema.Item in one context then I cannot create and save LocalSchema.Item in a different context due to missing origin property. enum LocalSchema: VersionedSchema { static var versionIdentifier: Schema.Version = .init(1, 0, 0) static var models: [any PersistentModel.Type] = [ Item.self ] @Model class Item { @Attribute(.unique) var title: String var created: Date var modified: Date init(title: String, created: Date, modified: Date) { self.title = title self.created = created self.modified = modified } } } enum RemoteSchema: VersionedSchema { static var versionIdentifier: Schema.Version = .init(1, 0, 0) static var models: [any PersistentModel.Type] = [ Item.self ] @Model class Item { var title: String var created: Date var modified: Date var origin: String init(title: String, created: Date, modified: Date, origin: String) { self.title = title self.created = created self.modified = modified self.origin = origin } } } In the above example, saving RemoteSchema.Item will cause LocalSchema.Item to fail. The error message I see is *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSManagedObject 0xa120f3750> setValue:forUndefinedKey:]: the entity Item is not key value coding-compliant for the key "origin".' Test Code @Test func createLocalItemWithManualSave() async throws { let context = ModelContext(try localStore()) let item = LocalSchema.Item(title: "local", created: .now, modified: .now) context.insert(item) try context.save() } @Test func createRemoteItemWithManualSave() async throws { let context = ModelContext(try remoteStore()) let item = RemoteSchema.Item(title: "remote", created: .now, modified: .now, origin: "from space") context.insert(item) try context.save() } func localStore() throws -> ModelContainer { let schema = Schema(versionedSchema: LocalSchema.self) let config = ModelConfiguration("local", schema: schema, isStoredInMemoryOnly: true, allowsSave: true, cloudKitDatabase: .none) return try ModelContainer(for: schema, configurations: config) } func remoteStore() throws -> ModelContainer { let schema = Schema(versionedSchema: RemoteSchema.self) let config = ModelConfiguration("remote", schema: schema, isStoredInMemoryOnly: true, allowsSave: true, cloudKitDatabase: .none) return try ModelContainer(for: schema, configurations: config) } I have created FB22310365
4
0
258
Mar ’26
SwiftData document-based app crashes on undo/redo without ModelContext.transaction(block:)
Overview I'm developing a document-based app for macOS using SwiftData. When I undo/redo changes using Command-Z/Command-Shift-Z, the app reliably crashes with the following error: SwiftData/ModelSnapshot.swift:46: Fatal error: Unexpected backing data for snapshot creation: SwiftData._FullFutureBackingData<DocumentTest.ChildItem> And before the app crashes, what always happens is that UndoManager stops removing/restoring instances of ChildItem (but continues to remove/restore instances of ParentItem). The issue goes away when I enclose the relevant code in ModelContext.transaction(block:). However, this shouldn't be necessary, as ModelContext.autosaveEnabled is true by default. The issues are occurring with Xcode 26.4 (17E192) and macOS Tahoe 26.4 (25E246). I have modified the macOS Document App project template to showcase the issue. The sample project, along with a screen recording of the crash, can be downloaded from here: https://drive.google.com/drive/folders/13bCB1qRZ6273BI81zW2zUUBraSvv6p5w?usp=share_link Is this expected behavior or should I file a bug report in Feedback Assistant? Steps to Reproduce To recreate the issue, follow these steps: Download and extract the "Xcode Project.zip" file linked above. Open the extracted "DocumentTest" project in Xcode. Build and run the "DocumentTest" app. In the document selection window, click "New Document" at the bottom-left. In the app, click the "+" button at the top-right to add a ParentItem with ChildItems. Click on the added ParentItem's button to add another ChildItem to it. Repeat steps 5–6 until you have 5 ParentItems with an additional ChildItem. Press Command-Z 10 times to undo all the changes. Press Command-Shift-Z 10 times to redo all the changes. Repeat steps 8–9 until UndoManager stops removing/restoring the additional ChildItem, and continue repeating them until the app eventually crashes (you may have to repeat them 5–10 times before the issue occurs). If you uncomment the ModelContext.transaction(block:) at line 13 of ContentView.swift and repeat the same steps above, no ChildItems will go missing and the app will not crash. Code ParentItem Model @Model final class ParentItem { var timestamp: Date @Relationship( deleteRule: .cascade, inverse: \ChildItem.parentItem ) var childItems: [ChildItem] = [] init(timestamp: Date) { self.timestamp = timestamp } } ChildItem Model @Model final class ChildItem { var index: Int var parentItem: ParentItem? init(index: Int) { self.index = index } } Creating, Inserting, and Linking ParentItem and ChildItem // Create and insert ParentItem let newParentItem = ParentItem( timestamp: Date() ) modelContext.insert(newParentItem) // Create and insert ChildItems var newChildItems: [ChildItem] = [] for index in 0..<Int.random(in: 2...8) { let newChildItem = ChildItem(index: index) newChildItems.append(newChildItem) modelContext.insert(newChildItem) } /* Establish relationship between ParentItem and ChildItems */ for newChildItem in newChildItems { newParentItem.childItems.append( newChildItem ) newChildItem.parentItem = newParentItem } Adding an Additional ChildItem to ParentItem // Uncommenting this block fixes the crash // try! modelContext.transaction { // Create and insert the new ChildItem let newChildItem = ChildItem( index: parentItem.childItems.count ) modelContext.insert(newChildItem) // Establish relationship to parentItem parentItem.childItems.append(newChildItem) newChildItem.parentItem = parentItem // }
0
0
594
Apr ’26
Does CKSyncEngine have to be re-initialized after an account change event?
According to this comment in the sample project on GitHub and this answer by Apple Staff, CKSyncEngine should be re-initialized after signing out or switching accounts so that "CKSyncEngine schedules a new fetch on init." But according to my tests, CKSyncEngine will schedule a fetch after having a signed out and signed in again, without me ever having to reset the serialized sync state. The documentation doesn't mentioned anywhere that CKSyncEngine should be re-initialized after an account change. In fact, it states that CKSyncEngine will reset its state internally on account changes. So if that's the case, then I'm very confused as to why the "official" recommendation is to re-initialize CKSyncEngine after receiving .signOut or .accountSwitch. Can someone please clarify the correct approach here?
1
0
420
Apr ’26
CKShare-style user-to-user sharing support in SwiftData
Hello everyone, I've really been enjoying SwiftData's approach to handling DBs, however sharing data between users has caused me quite some headaches. I am currently developing an app for my local theatre that will help the assistant directors with production planning and would need a way to share data. On some big productions we have 2 ADs, so they'd need to be able to share the project and do collaborative work on it. I don't need fancy real-time editing or anything. However, SwiftData exposing an equivalent to Core Data’s NSPersistentCloudKitContainer sharing APIs for CKShare-based user-to-user collaboration would be amazing. As the only thing supported is per-user private data sync, I’m currently considering a hybrid approach until the full project could be shared: SwiftData for the main private app data a small separate Core Data + CloudKit sharing stack only for the shared timetables for cast and crew Is that the recommended implementation today, or is there a better SwiftData-friendly way to do this? I also filed Feedback Assistant request FB22712510 asking for native SwiftData support for user-to-user CloudKit sharing. Thanks for any pointers or help! Best regards, Aedan
1
0
307
May ’26
CloudKit, cannot deploy private database initial schema to production
We’re using a private database with a custom zone. Record types and related schema are created programmatically rather than through the dashboard. When running the app in the development environment, I can see that data is saved and can be retrieved successfully. However, in the iCloud console, I don’t see any record types or even the custom zone. Additionally, I’m unable to deploy any schema to production because no changes are detected. Do you have any ideas on what we might be missing? Installing the app from TestFlight when trying to upload a record CloudKit reports this error: <CKError 0x13f40bb10: "Invalid Arguments" (12/2006); server message = "Cannot create new type MyType in production schema" ...>
2
0
479
Apr ’26
icloud imap lsub not following rfc 3501
LSUB always returns all the subscribed folders. For example lsub "" "test/*" returns a list of all the folders and not just subscribed folders that are subfolders of test. I.e, it returns the same folder list as lsub "" "*". For more details please see https://bugzilla.mozilla.org/show_bug.cgi?id=1817707#c15
2
0
143
Aug ’25
I want to make sure to make my app’s data persist across devices, updates, and reinstalls, you need to store it in the cloud.
i want to save data like images, text,amd mapviews with swiftui. It is only saved but if you delete the app of buy a new iPhone everything is deleted, how can I make if that the information saved on my app is saved even after I update the app, delete the app, or put the app in another iPhone with SwiftUI? i have watched youtube videos and im still confused,please help.
1
0
162
Oct ’25
CloudKit Sync with TestFlight
I'm working on a new app with SwiftData and now adding CloudKit Sync. Everything is working fine in the simulator against the development CloudKit Schema. I successfully deployed the schema to production. However, the TestFlight builds fail against production. This is what I see in the logs, but I haven't been able to find info on how to fix it. Help appreciated. CoreData+CloudKit: -[NSCloudKitMirroringDelegate _requestAbortedNotInitialized:](2205): <private> - Never successfully initialized and cannot execute request '<private>' due to error: Error Domain=CKErrorDomain Code=2 "CKInternalErrorDomain: 1011" UserInfo={ContainerID=<private>, NSDebugDescription=CKInternalErrorDomain: 1011, CKPartialErrors=<private>, RequestUUID=<private>, NSLocalizedDescription=<private>, CKErrorDescription=<private>, NSUnderlyingError=0x1078e9fe0 {Error Domain=CKInternalErrorDomain Code=1011 UserInfo={CKErrorDescription=<private>, NSLocalizedDescription=<private>, CKPartialErrors=<private>}}} CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(1153): <private>: Successfully set up CloudKit integration for store (<private>): <private> CoreData+CloudKit: -[NSCloudKitMirroringDelegate _enqueueRequest:]_block_invoke(1035): Failed to enqueue request: <private> Error Domain=NSCocoaErrorDomain Code=134417 UserInfo={NSLocalizedFailureReason=<private>}
1
0
160
Sep ’25
CKRecordZone deleted when second user accepts zone-wide CKShare
I'm seeing a critical issue where a custom CKRecordZone is consistently deleted server-side when a second iCloud account interacts with a zone-wide CKShare. I've reproduced this 20+ times across two days and have exhausted every client-side fix I can think of. Looking for guidance on what might be going wrong. Setup Container: iCloud.com.cohencooks (production app on App Store) Custom CKRecordZone in owner's private database Zone-wide CKShare(recordZoneID:) (iOS 15+ zone sharing) SwiftData with ModelConfiguration(cloudKitDatabase: .none) — no automatic CloudKit mirroring Acceptance via CKFetchShareMetadataOperation → CKContainer.accept(metadata) (no UICloudSharingController) Minimal reproduction // 1. Owner creates zone + share let zone = CKRecordZone(zoneName: "MyZone") try await privateDB.save(zone) let share = CKShare(recordZoneID: zone.zoneID) share[CKShare.SystemFieldKey.title] = "My Share" as CKRecordValue share.publicPermission = .readWrite let (results, _) = try await privateDB.modifyRecords(saving: [share], deleting: []) // 2. Owner pushes ~500 records to zone — all succeed // 3. Second user (different iCloud account) accepts share let metadata = try await container.shareMetadata(for: shareURL) try await container.accept(metadata) // 4. Owner's next CKFetchRecordZoneChangesOperation → zoneNotFound (code 26) // Zone is permanently gone. allRecordZones() confirms deletion. What I observe Three distinct failure patterns depending on configuration: Pattern 1 — publicPermission = .readWrite, no addParticipant: Zone dies instantly after acceptance. First push notification shows cloudkit.share changed (zone alive), second push notification returns zoneNotFound. The non-owner never successfully wrote anything. Pattern 2 — publicPermission = .none with explicit addParticipant: Zone survives acceptance and 2-3 minutes of bidirectional sync (non-owner pulls 578 records, pushes meal plans back). Then a push notification arrives and the zone is gone. This is dramatically better than Pattern 1 but still fails. Pattern 3 — Container destabilization after repeated testing: After 20+ create/delete cycles in one day, zones die from the owner's own push notifications — no second device involved at all. The container appears to enter an unstable state. Inconsistent state after deletion Here's something that might help narrow this down. After one of the zone deletions, I deployed the same build to a second device signed into a different iCloud account that had previously accepted the CKShare. Without sending a new invite, that device found the "Household" zone via allRecordZones() on sharedCloudDatabase — it could pull all 578 records, push updates, and the share URL still resolved. Meanwhile, the owner device (zone creator) gets "zone not found" from both allRecordZones() and direct recordZone(for:) on privateCloudDatabase. So it looks like the zone is deleted from the owner's private database, but the CKShare and zone records remain accessible to participants via the shared database. Participants can still read and write as if nothing happened — the owner just can't see the zone anymore. This also creates a recovery problem — when the owner creates a new zone with the same name, it gets a new CKShare URL, but the participant is still connected to the old "ghost" zone. The two sides are permanently split. Does this mean the zone deletion is happening through a path that doesn't properly clean up the sharing infrastructure? Is this expected behavior when a zone-wide CKShare's zone is deleted, or does it suggest the deletion is happening through an abnormal server-side path? What I've ruled out Hypothesis Test Result publicPermission = .readWrite Changed to .none + explicit addParticipant Zone survived longer but still eventually deleted Zone name tombstoning Tested 6 fresh names never used in this container All eventually deleted Non-owner writes causing deletion Gated ALL non-owner push methods (recipe, meal plan, grocery, photo, event) Zone still deleted database.save(share) vs modifyRecords Switched to modifyRecords(saving:deleting:) Zone still deleted NSPersistentCloudKitContainer interference Removed all Core Data CloudKit code Zone still deleted Double share acceptance Fresh app install, single acceptance only Zone still deleted Advanced Data Protection Neither account has ADP enabled Not the cause Programmatic vs system acceptance Tested both container.accept() and tapping share link Zone still deleted CloudKit Dashboard No ZoneDelete operation is visible in the logs. All operations are ZoneFetch, ZoneChanges, RecordQuery, RecordFetch. I do see EphemeralGroup operations targeting the custom zone — not sure what generates those. Comparison with working apps I compared my implementation with another app that uses the exact same zone-wide CKShare(recordZoneID:) pattern with publicPermission = .readWrite and programmatic acceptance — and it works. The main difference is that app uses CKSyncEngine (iOS 17+) rather than raw CKFetchRecordZoneChangesOperation / CKModifyRecordsOperation. Could CKSyncEngine be handling something internally that prevents this issue? Questions Is there a known interaction between zone-wide CKShare(recordZoneID:) acceptance and zone lifecycle that could cause zone deletion? Does CKSyncEngine handle zone-wide sharing differently than manual CKFetchRecordZoneChangesOperation + CKModifyRecordsOperation? What generates EphemeralGroup operations in CloudKit Dashboard? Could these trigger a zone delete? After 20+ zone create/delete cycles in a container, is there a server-side rate limit or tombstone mechanism that would destabilize new zones? Is the inconsistent state I described (zone gone from owner's private DB but still accessible from participant's shared DB) expected behavior, or does it indicate the deletion is happening through an abnormal path? Is the custom programmatic acceptance flow (CKFetchShareMetadataOperation → container.accept()) fully supported for zone-wide shares, or does it require UICloudSharingController? Any guidance would be greatly appreciated. This is blocking multi-user functionality for our app (mesa, a meal planning app on the App Store). Single-user sync works perfectly — the issue only manifests when a second iCloud account is involved. Environment: iOS 18.4.1, Xcode 16+, Swift, SwiftUI
1
0
318
Apr ’26
CloudKit: shared records creatorUserRecordID and lastModifiedUserRecordID
Hi, I am testing a situation with shared CKRecords where the data in the CKRecord syncs fine, but the creatorUserRecordID.recordName and lastModifiedUserRecordID.recordName shows "defaultOwner" (which maps to the CKCurrentUserDefaultName constant) even though I made sure I edit the CKRecord value from a different iCloud account. In fact, on the CloudKit dashboard, it shows the correct user recordIDs in the metadata for the 'Created' and 'Modified' fields, but not in the CKRecord. I am mostly testing this on the iPhone simulator with the debugger attached. Is that a possible reason for this, or is there some other reason the lastModifiedUserRecordID is showing the value for 'CKCurrentUserDefaultName'? It would be pretty difficult to build in functionality to look up changes by a different userID if this is the case.
1
0
231
Jul ’25
AppMigrationKit future plans
In the future, is there any plans to have AppMigrationKit for macOS-Windows cross transfers (or Linux, ChromeOS, HarmonyOS NEXT, etc)? Additionally, will the migration framework remain just iOS <-> Android or will it extend to Windows tablets, ChromeOS Tablets, HarmonyOS NEXT, KaiOS, Series 30+, Linux mobile, etc.
1
0
210
Nov ’25
CKSyncEngine for records with references
Is there any guidance for syncing records that have references to others regarding batching with the sync engine? For example, if I have hundreds of records to sync with many different types and references, do I need to keep track of how many records would be added because of reference properties? The sample and video doesn’t go into details about syncing records that have references to others so looking for lesser known rough edges.
1
0
56
2d
NSPersistentCloudKitContainer losing data
Some users of my app are reporting total loss of data while using the app. This is happening specifically when they enable iCloud sync. I am doing following private func setupContainer(enableICloud: Bool) { container = NSPersistentCloudKitContainer(name: "") container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy guard let description: NSPersistentStoreDescription = container.persistentStoreDescriptions.first else { fatalError() } description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) if enableICloud == false { description.cloudKitContainerOptions = nil } container.loadPersistentStores { description, error in if let error { // Handle error } } } When user clicks on Toggle to enable/disable iCloud sync I just set the description.cloudKitContainerOptions to nil and then user is asked to restart the app. Apart from that I periodically run the clear history func deleteTransactionHistory() { let sevenDaysAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())! let purgeHistoryRequest = NSPersistentHistoryChangeRequest.deleteHistory(before: sevenDaysAgo) let backgroundContext = container.newBackgroundContext() backgroundContext.performAndWait { try! backgroundContext.execute(purgeHistoryRequest) } }
4
0
1.3k
Nov ’25
Has anyone successfully used NSStagedMigrationManager?
I've been trying to build an example of NSStagedMigrationManager from some Core Data migration tests to replace a custom migration manager solution I'd constructed, without much success. The Core Data model has seven model versions. Most support lightweight migration, but two of the migrations in the middle of the sequence used NSMappingModel. In the first beta, just attempting to construct an NSStagedMigrationManager from the series of stages failed with an unrecognized selector. That no longer happens in b4, but I now get an error that "Duplicate version checksums across stages detected." If I restrict myself to just the first three versions of the model (that only require lightweight migration), I can build the migration manager. But if I attempt to use it to migrate a persistent store, it fails somewhere in NSPersistentStoreCoordinator with a nilError. The documentation is almost nonexistent for this process, and the WWDC session that introduced it isn't much more than a breezy overview. So maybe I'm holding it wrong? (And, yes: FB12339663)
Replies
7
Boosts
0
Views
2.4k
Activity
Mar ’26
How to switch between Core Data Persistent Stores?
What is the best way to switch between Core Data Persistent Stores? My use case is that I have a multi-user app that stores thousands of data items unique to each user. To me, having Persistent Stores for each user seems like the best design to keep their data separate and private. (If anyone believes that storing the data for all users in one Persistent Store is a better design, I'd appreciate hearing from them.) Customers might switch users 5 to 10 times a day. Switching users must be fast, say a second or two at most.
Replies
1
Boosts
0
Views
148
Activity
Jun ’25
Cannot create new CloudKit container after deleting all containers - need help
I accidentally deleted all CloudKit containers from the CloudKit Database console, and now I'm unable to create new containers. Both the CloudKit Console website and Xcode are not allowing me to create any new containers. Is there a way to restore the deleted containers? How can I create a new CloudKit container if the console website is not responding? Thank you.
Replies
2
Boosts
0
Views
235
Activity
Mar ’26
Orphaning a CKAsset
I'm running into a problem in my attempt to clear CKAssets on the iCloud server. The documentation for CKAsset says: If you no longer require an asset that’s on the server, you don’t delete it. Instead, orphan the asset by setting any fields that contain the asset to nil and then saving the record. CloudKit periodically deletes orphaned assets from the server. I'm deleting image file assets which are properties on an ImageReference type (largeImage and thumbNailImage properties). When I delete an image, I am setting those properties to nil and sending the record for the ImageReference to iCloud using the async CKDatabase.modifyRecords method. This always results in an error: <CKError 0x600000d92a60: "Asset File Not Found" (16/3002); "open error: 2 (No such file or directory)"> And of course the assets still appear in the CloudKit dashboard. What is the proper way of orphaning the assets on the CloudKit server?
Replies
4
Boosts
0
Views
487
Activity
Mar ’26
SwiftData Class Inheritance
Hi, I'm considering using the new SwiftData class inheritance for a new app I'm building. I have a few questions: Is it working well enough for production? I have a number of different object types in my app. Some of them are very similar, and there's always a balance to be struck when it comes to splitting them into different types using class inheritance. Are there some good advice on when to use multiple classes instead of squeezing my object types into a single class? Is there advice against using class inheritance in multiple levels (3-4)? Claes
Replies
1
Boosts
0
Views
155
Activity
Jul ’25
CloudKit: Efficient way to get user's rank in leaderboard without fetching all records?
CloudKit: Efficient way to get user's rank in leaderboard without fetching all records? I'm building a leaderboard feature using CloudKit's public database and need advice on the best approach to calculate a user's rank efficiently. Current Setup Record Structure: Record Type: LeaderboardScore Fields: period (String): "daily", "weekly", "monthly", "allTime" score (Int): User's score profile (Reference): Link to user's profile achievedAt (Date): Timestamp Leaderboard Display: Initially fetch first 15 users (sorted by score descending) Paginate to load more as user scrolls Show total player count Show current user's rank (even if not in top 15) The Challenge I can fetch the first 15 users easily with a sorted query, but I need to display the current user's rank regardless of their position. For example: User could be ranked #1 (in top 15) ✅ Easy User could be ranked #247 (not in top 15) ❌ How to get this efficiently? My Current Approach Query records with scores higher than the user's score and count them: // Count how many users scored higher let predicate = NSPredicate( format: "period == %@ AND score > %d", period, userScore ) // Rank = count + 1 Concerns For 1000+ users with better scores, this requires multiple paginated queries Even with desiredKeys: [], I'm concerned about performance and CloudKit request limits Questions Is there a CloudKit API I'm missing that can efficiently count records matching a predicate without fetching all the records and paginating? Is this approach acceptable for a leaderboard with 1K-10K users? Does fetching with desiredKeys: [] help significantly with performance? Are there any optimizations I should consider to make this more efficient? What's the recommended approach for calculating user rank in CloudKit at this scale? Current Scale Expected: 1,000-10,000 active users per leaderboard period Platform: iOS 17+, SwiftUI Any guidance on best practices for leaderboards usecase in CloudKit would be greatly appreciated!
Replies
3
Boosts
0
Views
270
Activity
Mar ’26
SwiftData ModelContext Pollution with Multiple ModelContainers and Schemas
I have two different VersionedSchema accessed via two different and distinct in-memory ModelContainers. However, both schemas have a model named Item. LocalSchema.Item and RemoteSchema.Item have slightly different properties. If I create and save RemoteSchema.Item in one context then I cannot create and save LocalSchema.Item in a different context due to missing origin property. enum LocalSchema: VersionedSchema { static var versionIdentifier: Schema.Version = .init(1, 0, 0) static var models: [any PersistentModel.Type] = [ Item.self ] @Model class Item { @Attribute(.unique) var title: String var created: Date var modified: Date init(title: String, created: Date, modified: Date) { self.title = title self.created = created self.modified = modified } } } enum RemoteSchema: VersionedSchema { static var versionIdentifier: Schema.Version = .init(1, 0, 0) static var models: [any PersistentModel.Type] = [ Item.self ] @Model class Item { var title: String var created: Date var modified: Date var origin: String init(title: String, created: Date, modified: Date, origin: String) { self.title = title self.created = created self.modified = modified self.origin = origin } } } In the above example, saving RemoteSchema.Item will cause LocalSchema.Item to fail. The error message I see is *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSManagedObject 0xa120f3750> setValue:forUndefinedKey:]: the entity Item is not key value coding-compliant for the key "origin".' Test Code @Test func createLocalItemWithManualSave() async throws { let context = ModelContext(try localStore()) let item = LocalSchema.Item(title: "local", created: .now, modified: .now) context.insert(item) try context.save() } @Test func createRemoteItemWithManualSave() async throws { let context = ModelContext(try remoteStore()) let item = RemoteSchema.Item(title: "remote", created: .now, modified: .now, origin: "from space") context.insert(item) try context.save() } func localStore() throws -> ModelContainer { let schema = Schema(versionedSchema: LocalSchema.self) let config = ModelConfiguration("local", schema: schema, isStoredInMemoryOnly: true, allowsSave: true, cloudKitDatabase: .none) return try ModelContainer(for: schema, configurations: config) } func remoteStore() throws -> ModelContainer { let schema = Schema(versionedSchema: RemoteSchema.self) let config = ModelConfiguration("remote", schema: schema, isStoredInMemoryOnly: true, allowsSave: true, cloudKitDatabase: .none) return try ModelContainer(for: schema, configurations: config) } I have created FB22310365
Replies
4
Boosts
0
Views
258
Activity
Mar ’26
SwiftData document-based app crashes on undo/redo without ModelContext.transaction(block:)
Overview I'm developing a document-based app for macOS using SwiftData. When I undo/redo changes using Command-Z/Command-Shift-Z, the app reliably crashes with the following error: SwiftData/ModelSnapshot.swift:46: Fatal error: Unexpected backing data for snapshot creation: SwiftData._FullFutureBackingData<DocumentTest.ChildItem> And before the app crashes, what always happens is that UndoManager stops removing/restoring instances of ChildItem (but continues to remove/restore instances of ParentItem). The issue goes away when I enclose the relevant code in ModelContext.transaction(block:). However, this shouldn't be necessary, as ModelContext.autosaveEnabled is true by default. The issues are occurring with Xcode 26.4 (17E192) and macOS Tahoe 26.4 (25E246). I have modified the macOS Document App project template to showcase the issue. The sample project, along with a screen recording of the crash, can be downloaded from here: https://drive.google.com/drive/folders/13bCB1qRZ6273BI81zW2zUUBraSvv6p5w?usp=share_link Is this expected behavior or should I file a bug report in Feedback Assistant? Steps to Reproduce To recreate the issue, follow these steps: Download and extract the "Xcode Project.zip" file linked above. Open the extracted "DocumentTest" project in Xcode. Build and run the "DocumentTest" app. In the document selection window, click "New Document" at the bottom-left. In the app, click the "+" button at the top-right to add a ParentItem with ChildItems. Click on the added ParentItem's button to add another ChildItem to it. Repeat steps 5–6 until you have 5 ParentItems with an additional ChildItem. Press Command-Z 10 times to undo all the changes. Press Command-Shift-Z 10 times to redo all the changes. Repeat steps 8–9 until UndoManager stops removing/restoring the additional ChildItem, and continue repeating them until the app eventually crashes (you may have to repeat them 5–10 times before the issue occurs). If you uncomment the ModelContext.transaction(block:) at line 13 of ContentView.swift and repeat the same steps above, no ChildItems will go missing and the app will not crash. Code ParentItem Model @Model final class ParentItem { var timestamp: Date @Relationship( deleteRule: .cascade, inverse: \ChildItem.parentItem ) var childItems: [ChildItem] = [] init(timestamp: Date) { self.timestamp = timestamp } } ChildItem Model @Model final class ChildItem { var index: Int var parentItem: ParentItem? init(index: Int) { self.index = index } } Creating, Inserting, and Linking ParentItem and ChildItem // Create and insert ParentItem let newParentItem = ParentItem( timestamp: Date() ) modelContext.insert(newParentItem) // Create and insert ChildItems var newChildItems: [ChildItem] = [] for index in 0..<Int.random(in: 2...8) { let newChildItem = ChildItem(index: index) newChildItems.append(newChildItem) modelContext.insert(newChildItem) } /* Establish relationship between ParentItem and ChildItems */ for newChildItem in newChildItems { newParentItem.childItems.append( newChildItem ) newChildItem.parentItem = newParentItem } Adding an Additional ChildItem to ParentItem // Uncommenting this block fixes the crash // try! modelContext.transaction { // Create and insert the new ChildItem let newChildItem = ChildItem( index: parentItem.childItems.count ) modelContext.insert(newChildItem) // Establish relationship to parentItem parentItem.childItems.append(newChildItem) newChildItem.parentItem = parentItem // }
Replies
0
Boosts
0
Views
594
Activity
Apr ’26
Does CKSyncEngine have to be re-initialized after an account change event?
According to this comment in the sample project on GitHub and this answer by Apple Staff, CKSyncEngine should be re-initialized after signing out or switching accounts so that "CKSyncEngine schedules a new fetch on init." But according to my tests, CKSyncEngine will schedule a fetch after having a signed out and signed in again, without me ever having to reset the serialized sync state. The documentation doesn't mentioned anywhere that CKSyncEngine should be re-initialized after an account change. In fact, it states that CKSyncEngine will reset its state internally on account changes. So if that's the case, then I'm very confused as to why the "official" recommendation is to re-initialize CKSyncEngine after receiving .signOut or .accountSwitch. Can someone please clarify the correct approach here?
Replies
1
Boosts
0
Views
420
Activity
Apr ’26
CKShare-style user-to-user sharing support in SwiftData
Hello everyone, I've really been enjoying SwiftData's approach to handling DBs, however sharing data between users has caused me quite some headaches. I am currently developing an app for my local theatre that will help the assistant directors with production planning and would need a way to share data. On some big productions we have 2 ADs, so they'd need to be able to share the project and do collaborative work on it. I don't need fancy real-time editing or anything. However, SwiftData exposing an equivalent to Core Data’s NSPersistentCloudKitContainer sharing APIs for CKShare-based user-to-user collaboration would be amazing. As the only thing supported is per-user private data sync, I’m currently considering a hybrid approach until the full project could be shared: SwiftData for the main private app data a small separate Core Data + CloudKit sharing stack only for the shared timetables for cast and crew Is that the recommended implementation today, or is there a better SwiftData-friendly way to do this? I also filed Feedback Assistant request FB22712510 asking for native SwiftData support for user-to-user CloudKit sharing. Thanks for any pointers or help! Best regards, Aedan
Replies
1
Boosts
0
Views
307
Activity
May ’26
CloudKit, cannot deploy private database initial schema to production
We’re using a private database with a custom zone. Record types and related schema are created programmatically rather than through the dashboard. When running the app in the development environment, I can see that data is saved and can be retrieved successfully. However, in the iCloud console, I don’t see any record types or even the custom zone. Additionally, I’m unable to deploy any schema to production because no changes are detected. Do you have any ideas on what we might be missing? Installing the app from TestFlight when trying to upload a record CloudKit reports this error: <CKError 0x13f40bb10: "Invalid Arguments" (12/2006); server message = "Cannot create new type MyType in production schema" ...>
Replies
2
Boosts
0
Views
479
Activity
Apr ’26
icloud imap lsub not following rfc 3501
LSUB always returns all the subscribed folders. For example lsub "" "test/*" returns a list of all the folders and not just subscribed folders that are subfolders of test. I.e, it returns the same folder list as lsub "" "*". For more details please see https://bugzilla.mozilla.org/show_bug.cgi?id=1817707#c15
Replies
2
Boosts
0
Views
143
Activity
Aug ’25
CloudKit Console and Unique Users
The CloudKit Console includes a Unique Users table in the Usage section. The numbers here are lower than what I would expect. Does this only track a certain percentage of users, e.g. users have opted in to share analytics with developers?
Replies
1
Boosts
0
Views
459
Activity
Oct ’25
I want to make sure to make my app’s data persist across devices, updates, and reinstalls, you need to store it in the cloud.
i want to save data like images, text,amd mapviews with swiftui. It is only saved but if you delete the app of buy a new iPhone everything is deleted, how can I make if that the information saved on my app is saved even after I update the app, delete the app, or put the app in another iPhone with SwiftUI? i have watched youtube videos and im still confused,please help.
Replies
1
Boosts
0
Views
162
Activity
Oct ’25
CloudKit Sync with TestFlight
I'm working on a new app with SwiftData and now adding CloudKit Sync. Everything is working fine in the simulator against the development CloudKit Schema. I successfully deployed the schema to production. However, the TestFlight builds fail against production. This is what I see in the logs, but I haven't been able to find info on how to fix it. Help appreciated. CoreData+CloudKit: -[NSCloudKitMirroringDelegate _requestAbortedNotInitialized:](2205): <private> - Never successfully initialized and cannot execute request '<private>' due to error: Error Domain=CKErrorDomain Code=2 "CKInternalErrorDomain: 1011" UserInfo={ContainerID=<private>, NSDebugDescription=CKInternalErrorDomain: 1011, CKPartialErrors=<private>, RequestUUID=<private>, NSLocalizedDescription=<private>, CKErrorDescription=<private>, NSUnderlyingError=0x1078e9fe0 {Error Domain=CKInternalErrorDomain Code=1011 UserInfo={CKErrorDescription=<private>, NSLocalizedDescription=<private>, CKPartialErrors=<private>}}} CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(1153): <private>: Successfully set up CloudKit integration for store (<private>): <private> CoreData+CloudKit: -[NSCloudKitMirroringDelegate _enqueueRequest:]_block_invoke(1035): Failed to enqueue request: <private> Error Domain=NSCocoaErrorDomain Code=134417 UserInfo={NSLocalizedFailureReason=<private>}
Replies
1
Boosts
0
Views
160
Activity
Sep ’25
CKRecordZone deleted when second user accepts zone-wide CKShare
I'm seeing a critical issue where a custom CKRecordZone is consistently deleted server-side when a second iCloud account interacts with a zone-wide CKShare. I've reproduced this 20+ times across two days and have exhausted every client-side fix I can think of. Looking for guidance on what might be going wrong. Setup Container: iCloud.com.cohencooks (production app on App Store) Custom CKRecordZone in owner's private database Zone-wide CKShare(recordZoneID:) (iOS 15+ zone sharing) SwiftData with ModelConfiguration(cloudKitDatabase: .none) — no automatic CloudKit mirroring Acceptance via CKFetchShareMetadataOperation → CKContainer.accept(metadata) (no UICloudSharingController) Minimal reproduction // 1. Owner creates zone + share let zone = CKRecordZone(zoneName: "MyZone") try await privateDB.save(zone) let share = CKShare(recordZoneID: zone.zoneID) share[CKShare.SystemFieldKey.title] = "My Share" as CKRecordValue share.publicPermission = .readWrite let (results, _) = try await privateDB.modifyRecords(saving: [share], deleting: []) // 2. Owner pushes ~500 records to zone — all succeed // 3. Second user (different iCloud account) accepts share let metadata = try await container.shareMetadata(for: shareURL) try await container.accept(metadata) // 4. Owner's next CKFetchRecordZoneChangesOperation → zoneNotFound (code 26) // Zone is permanently gone. allRecordZones() confirms deletion. What I observe Three distinct failure patterns depending on configuration: Pattern 1 — publicPermission = .readWrite, no addParticipant: Zone dies instantly after acceptance. First push notification shows cloudkit.share changed (zone alive), second push notification returns zoneNotFound. The non-owner never successfully wrote anything. Pattern 2 — publicPermission = .none with explicit addParticipant: Zone survives acceptance and 2-3 minutes of bidirectional sync (non-owner pulls 578 records, pushes meal plans back). Then a push notification arrives and the zone is gone. This is dramatically better than Pattern 1 but still fails. Pattern 3 — Container destabilization after repeated testing: After 20+ create/delete cycles in one day, zones die from the owner's own push notifications — no second device involved at all. The container appears to enter an unstable state. Inconsistent state after deletion Here's something that might help narrow this down. After one of the zone deletions, I deployed the same build to a second device signed into a different iCloud account that had previously accepted the CKShare. Without sending a new invite, that device found the "Household" zone via allRecordZones() on sharedCloudDatabase — it could pull all 578 records, push updates, and the share URL still resolved. Meanwhile, the owner device (zone creator) gets "zone not found" from both allRecordZones() and direct recordZone(for:) on privateCloudDatabase. So it looks like the zone is deleted from the owner's private database, but the CKShare and zone records remain accessible to participants via the shared database. Participants can still read and write as if nothing happened — the owner just can't see the zone anymore. This also creates a recovery problem — when the owner creates a new zone with the same name, it gets a new CKShare URL, but the participant is still connected to the old "ghost" zone. The two sides are permanently split. Does this mean the zone deletion is happening through a path that doesn't properly clean up the sharing infrastructure? Is this expected behavior when a zone-wide CKShare's zone is deleted, or does it suggest the deletion is happening through an abnormal server-side path? What I've ruled out Hypothesis Test Result publicPermission = .readWrite Changed to .none + explicit addParticipant Zone survived longer but still eventually deleted Zone name tombstoning Tested 6 fresh names never used in this container All eventually deleted Non-owner writes causing deletion Gated ALL non-owner push methods (recipe, meal plan, grocery, photo, event) Zone still deleted database.save(share) vs modifyRecords Switched to modifyRecords(saving:deleting:) Zone still deleted NSPersistentCloudKitContainer interference Removed all Core Data CloudKit code Zone still deleted Double share acceptance Fresh app install, single acceptance only Zone still deleted Advanced Data Protection Neither account has ADP enabled Not the cause Programmatic vs system acceptance Tested both container.accept() and tapping share link Zone still deleted CloudKit Dashboard No ZoneDelete operation is visible in the logs. All operations are ZoneFetch, ZoneChanges, RecordQuery, RecordFetch. I do see EphemeralGroup operations targeting the custom zone — not sure what generates those. Comparison with working apps I compared my implementation with another app that uses the exact same zone-wide CKShare(recordZoneID:) pattern with publicPermission = .readWrite and programmatic acceptance — and it works. The main difference is that app uses CKSyncEngine (iOS 17+) rather than raw CKFetchRecordZoneChangesOperation / CKModifyRecordsOperation. Could CKSyncEngine be handling something internally that prevents this issue? Questions Is there a known interaction between zone-wide CKShare(recordZoneID:) acceptance and zone lifecycle that could cause zone deletion? Does CKSyncEngine handle zone-wide sharing differently than manual CKFetchRecordZoneChangesOperation + CKModifyRecordsOperation? What generates EphemeralGroup operations in CloudKit Dashboard? Could these trigger a zone delete? After 20+ zone create/delete cycles in a container, is there a server-side rate limit or tombstone mechanism that would destabilize new zones? Is the inconsistent state I described (zone gone from owner's private DB but still accessible from participant's shared DB) expected behavior, or does it indicate the deletion is happening through an abnormal path? Is the custom programmatic acceptance flow (CKFetchShareMetadataOperation → container.accept()) fully supported for zone-wide shares, or does it require UICloudSharingController? Any guidance would be greatly appreciated. This is blocking multi-user functionality for our app (mesa, a meal planning app on the App Store). Single-user sync works perfectly — the issue only manifests when a second iCloud account is involved. Environment: iOS 18.4.1, Xcode 16+, Swift, SwiftUI
Replies
1
Boosts
0
Views
318
Activity
Apr ’26
CloudKit: shared records creatorUserRecordID and lastModifiedUserRecordID
Hi, I am testing a situation with shared CKRecords where the data in the CKRecord syncs fine, but the creatorUserRecordID.recordName and lastModifiedUserRecordID.recordName shows "defaultOwner" (which maps to the CKCurrentUserDefaultName constant) even though I made sure I edit the CKRecord value from a different iCloud account. In fact, on the CloudKit dashboard, it shows the correct user recordIDs in the metadata for the 'Created' and 'Modified' fields, but not in the CKRecord. I am mostly testing this on the iPhone simulator with the debugger attached. Is that a possible reason for this, or is there some other reason the lastModifiedUserRecordID is showing the value for 'CKCurrentUserDefaultName'? It would be pretty difficult to build in functionality to look up changes by a different userID if this is the case.
Replies
1
Boosts
0
Views
231
Activity
Jul ’25
AppMigrationKit future plans
In the future, is there any plans to have AppMigrationKit for macOS-Windows cross transfers (or Linux, ChromeOS, HarmonyOS NEXT, etc)? Additionally, will the migration framework remain just iOS <-> Android or will it extend to Windows tablets, ChromeOS Tablets, HarmonyOS NEXT, KaiOS, Series 30+, Linux mobile, etc.
Replies
1
Boosts
0
Views
210
Activity
Nov ’25
CKSyncEngine for records with references
Is there any guidance for syncing records that have references to others regarding batching with the sync engine? For example, if I have hundreds of records to sync with many different types and references, do I need to keep track of how many records would be added because of reference properties? The sample and video doesn’t go into details about syncing records that have references to others so looking for lesser known rough edges.
Replies
1
Boosts
0
Views
56
Activity
2d
NSPersistentCloudKitContainer losing data
Some users of my app are reporting total loss of data while using the app. This is happening specifically when they enable iCloud sync. I am doing following private func setupContainer(enableICloud: Bool) { container = NSPersistentCloudKitContainer(name: "") container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy guard let description: NSPersistentStoreDescription = container.persistentStoreDescriptions.first else { fatalError() } description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) if enableICloud == false { description.cloudKitContainerOptions = nil } container.loadPersistentStores { description, error in if let error { // Handle error } } } When user clicks on Toggle to enable/disable iCloud sync I just set the description.cloudKitContainerOptions to nil and then user is asked to restart the app. Apart from that I periodically run the clear history func deleteTransactionHistory() { let sevenDaysAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())! let purgeHistoryRequest = NSPersistentHistoryChangeRequest.deleteHistory(before: sevenDaysAgo) let backgroundContext = container.newBackgroundContext() backgroundContext.performAndWait { try! backgroundContext.execute(purgeHistoryRequest) } }
Replies
4
Boosts
0
Views
1.3k
Activity
Nov ’25