iCloud & Data

RSS for tag

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

CloudKit Documentation

Posts under iCloud & Data subtopic

Post

Replies

Boosts

Views

Activity

Fatal error on rollback after delete
I encountered an error when trying to rollback context after deleting some model with multiple one-to-many relationships when encountered a problem later in a deleting method and before saving the changes. Something like this: do { // Fetch model modelContext.delete(model) // Do some async work that potentially throws try modelContext.save() } catch { modelContext.rollback() } When relationship is empty - the parent has no children - I can safely delete and rollback with no issues. However, when there is even one child when I call even this code: modelContext.delete(someModel) modelContext.rollback() I'm getting a fatal error: SwiftData/ModelSnapshot.swift:46: Fatal error: Unexpected backing data for snapshot creation: SwiftData._FullFutureBackingData<ChildModel> I use ModelContext from within the ModelActor but using mainContext changes nothing. My ModelContainer is quite simple and problem occurs on both in-memory and persistent storage, with or without CloudKit database being enabled. I can isolate the issue in test environment, so the model that's being deleted (or any other) is not being accessed by any other part of the application. However, problem looks the same in the real app. I also changed the target version of iOS from 18.0 to 26.0, but to no avail. My models look kind of like this: @Model final class ParentModel { var name: String @Relationship(deleteRule: .cascade, inverse: \ChildModel.parent) var children: [ChildModel]? init(name: String) { self.name = name } } @Model final class ChildModel { var name: String @Relationship(deleteRule: .nullify) var parent: ParentModel? init(name: String) { self.name = name } } I tried many approaches that didn't help: Fetching all children (via fetch) just to "populate" the context Accessing all children on parent model (via let _ = parentModel.children?.count) Deleting all children reading models from parent: for child in parentModel.children ?? [] { modelContext.delete(child) } Deleting all children like this: let parentPersistentModelID = parentModel.persistentModelID modelContext.delete(model: ChildModel.self, where: #Predicate { $0.parent.persistentModelID == parentPersistentModelID }, includeSubclasses: true) Removing @Relationship(deleteRule: .nullify) from ChildModel relationship definition I found 2 solution for the problem: To manually fetch and delete all children prior to deleting parent: let parentPersistentModelID = parentModel.persistentModelID for child in try modelContext.fetch(FetchDescriptor<ChildModel>(predicate: #Predicate { $0.parent.persistentModelID == parentPersistentModelID })) { modelContext.delete(child) } modelContext.delete(parentModel) Trying to run my code in child context (let childContext = ModelContext(modelContext.container)) All that sounds to me like a problem deep inside Swift Data itself. The first solution I found, fetching potentially hundreds of child models just to delete them in case I might need to rollback changes on some error, sounds like awful waste of resources to me. The second one however seems to work fine has that drawback that I can't fully test my code. Right now I can wrap the context (literally creating class that holds ModelContext and calls its methods) and in tests for throwing methods force them to throw. By creating scratch ModelContext I loose that possibility. What might be the real issue here? Am I missing something?
0
0
12
7h
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
62
9h
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" ...>
1
0
118
3d
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
123
3d
Bug? SwiftData + inheritance + optional many-to-one relationship
I've spent a few months writing an app that uses SwiftData with inheritance. Everything worked well until I tried adding CloudKit support. To do so, I had to make all relationships optional, which exposed what appears to be a bug. Note that this isn't a CloudKit issue -- it happens even when CloudKit is disabled -- but it's due to the requirement for optional relationships. In the code below, I get the following error on the second call to modelContext.save() when the button is clicked: Could not cast value of type 'SwiftData.PersistentIdentifier' (0x1ef510b68) to 'SimplePersistenceIdentifierTest.Computer' (0x1025884e0). I was surprised to find zero hit when Googling "Could not cast value of type 'SwiftData.PersistentIdentifier'". Some things to note: Calling teacher.computers?.append(computer) instead of computer.teacher = teacher results in the same error. It only happens when Teacher inherits Person. It only happens if modelContext.save() is called both times. It works if the first modelContext.save() is commented out. If the second modelContext.save()is commented out, the error occurs the second time the model context is saved (whether explicitly or implicitly). Keep in mind this is a super simple repro written to generate on demand the error I'm seeing in a normal app. In my app, modelContext.save() must be called in some places to update the UI immediately, sometimes resulting in the error seconds later when the model context is saved automatically. Not calling modelContext.save() doesn't appear to be an option. To be sure, I'm new to this ecosystem so I'd be thrilled if I've missed something obvious! Any thoughts are appreciated. import Foundation import SwiftData import SwiftUI struct ContentView: View { @Environment(\.modelContext) var modelContext var body: some View { VStack { Button("Do it") { let teacher = Teacher() let computer = Computer() modelContext.insert(teacher) modelContext.insert(computer) try! modelContext.save() computer.teacher = teacher try! modelContext.save() } } } } @Model class Computer { @Relationship(deleteRule: .nullify) var teacher: Teacher? init() {} } @Model class Person { init() {} } @available(iOS 26.0, macOS 26.0, *) @Model class Teacher: Person { @Relationship(deleteRule: .nullify, inverse: \Computer.teacher) public var computers: [Computer]? = [] override init() { super.init() } }
9
2
445
6d
Swift Data Recovery
Hi Writing an app in Swift on Xcode for my iPhone, all software is the latest version. If after making a minor change and re-building all the application data has disappeared, is there a way to see if it is still in the .modelContainer and just not showing up?
2
0
614
1w
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
266
1w
SwiftData Models and SortDesc. Only Work in One Swift File
Hey everyone, I found a possible SwiftData Release-only issue with nested sort descriptors on an optional relationship. In a minimal repro, sorting a @Query by a nested optional relationship key path like: SortDescriptor(\InvestigationPhotoAsset.imageAnalysis?.overallAestheticsScore, order: .reverse) works in Debug, but crashes at runtime in Release. The surprising part is that the crash depends on file layout: if the active SwiftData models and the sort logic are kept in the same Swift file, the app works if the same models are split into separate files, the Release build crashes, 'Debug' will also work The repro was reduced to just two SwiftData models: InvestigationPhotoAsset InvestigationImageAnalysis So this looks less like an app-modeling issue and more like a SwiftData/compiler/codegen issue related to nested sort metadata in optimized builds. If useful, I can also give you a slightly more formal version with a title and code snippet block. Please check out the code example here Has anyone faced something similar? Bug is reported as FB22173905
4
0
236
1w
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
84
1w
Mac Assigning NSManagedObject to NSPersistentStore
Hello, I have a iOS app I was looking at porting to Mac. I'm having an issue with both the Mac (Designed for iPad) and Mac Catalyst Destinations. I can't test Mac due to too many build issues. I'm trying to assign a new NSManagedObject into a NSPersistentStore. let object = MyObject(context: context) context.assign(object, to: nsPersistentStore) This works fine for iOS/iOS Simulator/iPhone/iPad. But on the Mac it's crashing with FAULT: NSInvalidArgumentException: Can't assign an object to a store that does not contain the object's entity.; { Thread 1: "Can't assign an object to a store that does not contain the object's entity."
6
0
243
1w
Missing demo project
Hi forum! I’m currently following a series of videos about SwiftData. In the WWDC23 Build an app with SwiftData video, it mentions that you can follow up with a demo project. However, I’m encountering an issue (at least in my case) where there’s no link on the entire page to download the project. I can download the video and other resources (even using the Developer’s App), but there’s no link for the project. Does anyone else face this issue? Is it possible that the project has been removed? I’m using my developer (single user) account, by the way. Any guidance would be greatly appreciated!
1
0
305
1w
Help Rescuing SwiftData Schema with Non-Optional Transformables
I currently have a schema in production (cloudKit and local files) containing non-optional transformable values, e.g. @Attribute(.transformable(by: TestTransformer.self)) var number: TestTransformable = TestTransformable.init(value: 100) Unfortunately, this is preventing any migration from succeeding (documented at length in FB22151570). Briefly summarized, any migration from a Schema containing non-optional transformable values fails between willMigrate and didMigrate with the error "Can't find model for source store". This occurs for all migrations, including lightweight with a migration plan, lightweight without a plan, and custom migrations. Worst of all, this also prevents migration to optional transformable values, or the elimination of the transformable value entirely, leaving us completely stuck. (note: optional transformable values only work when they have a default value set to nil, otherwise even these have issues migrating) We already have features being blocked by this issue, and would like to preserve user-data while restoring our ability to move forwards with database. Are there any known workarounds for using SwiftData (+CloudKit) when schema migration is non-operational?
2
0
124
2w
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.2k
2w
Core data destroyPersistentStore, not working for some
Hi all I have a problem with core data, where when a new user login that is different from the previous user i delete all of core data by using "destroyPersistentStore". Then i recreate the persistent store, this works when i am testing. When it does not work for one of my users when she test. I am not sure why this should not work, i have added the code i use to destroy the persistent store below. This code is run after login but before the view changes away from my login view. // Retrieves the shared `AppDelegate` instance guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return } appDelegate.destroyDataSyncBackground() // Get a reference to a NSPersistentStoreCoordinator let storeContainer = appDelegate.persistentContainer.persistentStoreCoordinator // Delete each existing persistent store for store in storeContainer.persistentStores { if let url = store.url { do { try storeContainer.destroyPersistentStore( at: url, ofType: store.type, options: nil ) } catch { print("Failed to deleted all") } } else { print("Failed to deleted all") } } // Re-create the persistent container appDelegate.persistentContainer = NSPersistentContainer( name: "CueToCue" // the name of // a .xcdatamodeld file ) // Calling loadPersistentStores will re-create the // persistent stores appDelegate.persistentContainer.loadPersistentStores { (store, error) in // Handle errors let description = NSPersistentStoreDescription() description.shouldMigrateStoreAutomatically = true description.shouldInferMappingModelAutomatically = true appDelegate.persistentContainer.persistentStoreDescriptions = [description] } // Reapply context configuration let viewContext = appDelegate.persistentContainer.viewContext viewContext.automaticallyMergesChangesFromParent = true viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy do { try viewContext.save() appDelegate.recreateDataSyncBackground() } catch { print("Debug: saving delete all failed.") } } The function "destroyDataSyncBackground" just set the my sync class to nil so stop any changes to core data while the code is running. The function "recreateDataSyncBackground" recreate the sync class so fetch, post and patch requests is made again.
3
0
119
2w
Sharing all container content
I've understood that SwiftData is not abled to share the whole content of a cloudkit database. So I'm trying to rewrite everything. Does someone knows id Sharing is coming on SwiftData at WWDC 26? Anyway, can someone can point me an example a a configured coredata stack that share all its content with other icloud users (with sharing pane and accept invitation code). At this step, on the owner side, I see some data in the default zone of my private container but nothing is visible on the shared zone. Maybe I don't understand where and when I should check shared data in cloudkit console. Need Help also here. See below by configuration stack: // Core Data container public lazy var container: NSPersistentContainer = { switch delegate.usage() { case .preview : return previewContainer() case .local : return localContainer() case .cloudKit : return cloudKitContainer() } }() private func cloudKitContainer() -> NSPersistentContainer { let modelURL = delegate.modelURL() let modelName = modelURL.deletingPathExtension().lastPathComponent guard let model = NSManagedObjectModel(contentsOf: modelURL) else { fatalError("Could not load Core Data model from \(modelURL)") } let container = NSPersistentCloudKitContainer( name: modelName, managedObjectModel: model ) let groupIdentifier = AppManager.shared.groupIdentifier guard let appGroupURL = FileManager.default.containerURL ( forSecurityApplicationGroupIdentifier: groupIdentifier ) else { fatalError("App Group not found: \(groupIdentifier)") } // MARK: - Private Store Configuration let privateStoreURL = appGroupURL.appendingPathComponent("\(modelName).sqlite") let privateStoreDescription = NSPersistentStoreDescription(url: privateStoreURL) // Persistent history tracking (MANDATORY) privateStoreDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) privateStoreDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) // CloudKit options for private database // Core Data automatically uses the default zone: com.apple.coredata.cloudkit.zone let privateCloudKitOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: delegate.cloudKitIdentifier()) privateCloudKitOptions.databaseScope = .private privateStoreDescription.cloudKitContainerOptions = privateCloudKitOptions // MARK: - Shared Store Configuration guard let sharedStoreDescription = privateStoreDescription.copy() as? NSPersistentStoreDescription else { fatalError("Create shareDesc error") } // The shared store receives zones that others share with us via CloudKit's shared database sharedStoreDescription.url = appGroupURL.appendingPathComponent("\(modelName)-shared.sqlite") // Persistent history tracking (MANDATORY) sharedStoreDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) sharedStoreDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) // CloudKit options for shared database // This syncs data from CloudKit shared zones when we accept share invitations let sharedCloudKitOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: delegate.cloudKitIdentifier()) sharedCloudKitOptions.databaseScope = .shared sharedStoreDescription.cloudKitContainerOptions = sharedCloudKitOptions // Configure both stores // Private store: com.apple.coredata.cloudkit.zone in private database // Shared store: Receives shared zones we're invited to container.persistentStoreDescriptions = [privateStoreDescription, sharedStoreDescription] container.loadPersistentStores { storeDescription, error in if let error = error as NSError? { fatalError("DB init error:\(error.localizedDescription)") } else if let cloudKitContiainerOptions = storeDescription.cloudKitContainerOptions { switch cloudKitContiainerOptions.databaseScope { case .private: self._privatePersistentStore = container.persistentStoreCoordinator.persistentStore(for: privateStoreDescription.url!) case .shared: self._sharedPersistentStore = container.persistentStoreCoordinator.persistentStore(for: sharedStoreDescription.url!) default: break } } let scope = storeDescription.cloudKitContainerOptions?.databaseScope == .shared ? "shared" : "private" print("✅ \(scope) store loaded at: \(storeDescription.url?.path ?? "unknown")") } // Auto-merge container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy do { try container.viewContext.setQueryGenerationFrom(.current) } catch { fatalError("Fail to pin viewContext to the current generation:\(error)") } return container }
7
0
238
2w
CloudKit references — is this a forward reference or a back reference?
I'm trying to understand the terminology around forward vs backward references in CloudKit. Say I have two record types: User LeaderboardScore (a score belongs to a user) The score record stores a user reference: score["user"] = CKRecord.Reference( recordID: userRecordID, action: .deleteSelf ) So: LeaderboardScore → User The user record does not store any references to scores From a data-model perspective: Is this considered a forward reference (child → parent)? Or a back reference, since the score is "pointing back" to its owner? My use case is having leaderboard in my app and so i have created a user table to store all the users and a score table for saving the scores of each user of the app.
4
0
170
2w
CloudKit Sync Stalls During Initial Large Data Hydration on New Device (SwiftData Local-First Architecture)
Hi everyone, I’m facing an issue with CloudKit sync getting stuck during initial device migration in my SwiftData-based app. The app follows a local-first architecture using SwiftData + CloudKit sync, and works correctly for: ✔ Incremental sync ✔ Bi-directional updates ✔ Small datasets However, when onboarding a new device with large historical data, sync becomes extremely slow or appears stuck. Even after two hours data is not fully synced. ~6900 Transactions 🚨 Problem When installing the app on a new iPhone and enabling iCloud sync: • Initial hydration starts • A small amount of data syncs • Then sync stalls indefinitely Observed behaviour: • iPhone → Mac sync works (new changes sync back) • Mac → iPhone large historical migration gets stuck • Reinstalling app / clearing container does not resolve issue • Sync never completes full migration This gives the impression that: CloudKit is trickling data but not progressing after a certain threshold. The architecture is: • SwiftData local store • Manual CloudKit sync layer • Local-first persistence • Background push/pull sync So I understand: ✔ Conflict resolution is custom ✔ Initial import may not be optimized by default But I expected CloudKit to eventually deliver all records. Instead, the new device remains permanently in a “partial state”. ⸻ 🔍 Observations • No fatal CloudKit errors • No rate-limit errors • No quota issues • iCloud is available • Sync state remains “Ready” • Hydration remains “mostlyReady” Meaning: CloudKit does not report failure — but data transfer halts. ⸻ 🤔 Questions Would appreciate guidance on: Is CloudKit designed to support large initial dataset migration via manual sync layers? Or is this a known limitation vs NSPersistentCloudKitContainer? ⸻ Does CloudKit internally throttle historical record fetches? Could it silently stall without error when record volume is high? ⸻ Is there any recommended strategy for: • Bulk initial migration • Progressive hydration • Forcing forward sync progress ⸻ Should initial migration be handled outside CloudKit (e.g. via file transfer / backup restore) before enabling sync? ⸻ 🎯 Goal I want to support: • Large historical onboarding • Multi-device sync • User-visible progress Without forcing migration to Core Data. ⸻ 🙏 Any advice on: • Best practices • Debugging approach • CloudKit behavior in such scenarios would be greatly appreciated. Thank you!
1
0
138
3w
SwiftData Unidirectional Relationships
Hi everyone I would like to achieve having unidirectional relationships in my SwiftData project (which I believe is possible: https://developer.apple.com/documentation/updates/swiftdata?changes=_9) but I'm afraid I'm struggling to overcome the errors I'm experiencing. For example, I have the following models: @Model final class Quota { @Attribute(.unique) var id: UUID var allowance: Int @Relationship(inverse: nil) var fish: Fish init(id: UUID = UUID(), fish: Fish, allowance: Int) { self.id = id self.fish = fish self.allowance = allowance } } @Model final class Fish { @Attribute(.unique) var id: Int var name: String init(id: Int, name: String) { self.id = id, self.name = name } } However, when I attempt to save a quota as so: let quota: Quota = .init(fish: Fish(id: 2, name: "Salmon"), allowance: 50) modelContext?.insert(quota) try save() I keep getting the following error: SwiftData.DefaultStore save failed with error: Error Domain=NSCocoaErrorDomain Code=1570 "%{PROPERTY}@ is a required value." UserInfo={NSValidationErrorObject=<NSManagedObject: 0x600002217390> (entity: Fish; id: 0x83319d001151328d <x-coredata://C76A2A64-146E-432F-A565-319B5A2F23F5/Fish/p12>; data: { id = nil; }), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=id, NSValidationErrorValue=null} %{PROPERTY}@ is a required value. However, if I set up Quota and Fish with an inverse relationship then the data saves as expected, so I'm a little confused. Is there anyone out there who can provide some guidance as to why I'm seeing this error when I try to save a record in SwiftData with no inverse relationship? I do fully understand about unidirectional vs bidirectional relationships but I have a scenario where I need the relationship to be unidirectional. Also, as a side note, the Fish record already exists in my database, but if I delete it and try to save the record I still see this error. Thank you so much in advance for any help.
1
0
175
3w
iCloud Account Signing Out
I have several macOS applications that use CloudKit. I need to test and finds out what happens when the user signs out of their iCloud account. That's because the application may lose data after signing out and then signing in again. Every time I do that, it'll take 15, 20 minutes... I don't time it, but it takes quite a gigantic time to sign out as the spinner keeps rolling. Why does it take so long to just sign out? This sign out effect is untestable because it takes a long time to sign out of an iCloud account and then make changes to the code and then test again. In case you need to know, my system version is Sequoia 15.7.
2
0
135
3w
Importing Data into SwiftData in the Background Using ModelActor and @Query
I have an app with fairly typical requirements - I need to insert some data (in my case from the network but could be anything) and I want to do it in the background to keep the UI responsive. I'm using SwiftData. I've created a ModelActor that does the importing and using the debugger I can confirm that the data is indeed being inserted. On the UI side, I'm using @Query and a SwiftUI List to display the data but what I am seeing is that @Query is not updating as the data is being inserted. I have to quit and re-launch the app in order for the data to appear, almost like the context running the UI isn't communicating with the context in the ModelActor. I've included a barebones sample project. To reproduce the issue, tap the 'Background Insert' button. You'll see logs that show items being inserted but the UI is not showing any data. I've tested on the just released iOS 18b3 seed (22A5307f). The sample project is here: https://hanchor.s3.amazonaws.com/misc/SwiftDataBackgroundV2.zip
24
13
6.3k
3w
Fatal error on rollback after delete
I encountered an error when trying to rollback context after deleting some model with multiple one-to-many relationships when encountered a problem later in a deleting method and before saving the changes. Something like this: do { // Fetch model modelContext.delete(model) // Do some async work that potentially throws try modelContext.save() } catch { modelContext.rollback() } When relationship is empty - the parent has no children - I can safely delete and rollback with no issues. However, when there is even one child when I call even this code: modelContext.delete(someModel) modelContext.rollback() I'm getting a fatal error: SwiftData/ModelSnapshot.swift:46: Fatal error: Unexpected backing data for snapshot creation: SwiftData._FullFutureBackingData<ChildModel> I use ModelContext from within the ModelActor but using mainContext changes nothing. My ModelContainer is quite simple and problem occurs on both in-memory and persistent storage, with or without CloudKit database being enabled. I can isolate the issue in test environment, so the model that's being deleted (or any other) is not being accessed by any other part of the application. However, problem looks the same in the real app. I also changed the target version of iOS from 18.0 to 26.0, but to no avail. My models look kind of like this: @Model final class ParentModel { var name: String @Relationship(deleteRule: .cascade, inverse: \ChildModel.parent) var children: [ChildModel]? init(name: String) { self.name = name } } @Model final class ChildModel { var name: String @Relationship(deleteRule: .nullify) var parent: ParentModel? init(name: String) { self.name = name } } I tried many approaches that didn't help: Fetching all children (via fetch) just to "populate" the context Accessing all children on parent model (via let _ = parentModel.children?.count) Deleting all children reading models from parent: for child in parentModel.children ?? [] { modelContext.delete(child) } Deleting all children like this: let parentPersistentModelID = parentModel.persistentModelID modelContext.delete(model: ChildModel.self, where: #Predicate { $0.parent.persistentModelID == parentPersistentModelID }, includeSubclasses: true) Removing @Relationship(deleteRule: .nullify) from ChildModel relationship definition I found 2 solution for the problem: To manually fetch and delete all children prior to deleting parent: let parentPersistentModelID = parentModel.persistentModelID for child in try modelContext.fetch(FetchDescriptor<ChildModel>(predicate: #Predicate { $0.parent.persistentModelID == parentPersistentModelID })) { modelContext.delete(child) } modelContext.delete(parentModel) Trying to run my code in child context (let childContext = ModelContext(modelContext.container)) All that sounds to me like a problem deep inside Swift Data itself. The first solution I found, fetching potentially hundreds of child models just to delete them in case I might need to rollback changes on some error, sounds like awful waste of resources to me. The second one however seems to work fine has that drawback that I can't fully test my code. Right now I can wrap the context (literally creating class that holds ModelContext and calls its methods) and in tests for throwing methods force them to throw. By creating scratch ModelContext I loose that possibility. What might be the real issue here? Am I missing something?
Replies
0
Boosts
0
Views
12
Activity
7h
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
62
Activity
9h
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
1
Boosts
0
Views
118
Activity
3d
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
123
Activity
3d
Bug? SwiftData + inheritance + optional many-to-one relationship
I've spent a few months writing an app that uses SwiftData with inheritance. Everything worked well until I tried adding CloudKit support. To do so, I had to make all relationships optional, which exposed what appears to be a bug. Note that this isn't a CloudKit issue -- it happens even when CloudKit is disabled -- but it's due to the requirement for optional relationships. In the code below, I get the following error on the second call to modelContext.save() when the button is clicked: Could not cast value of type 'SwiftData.PersistentIdentifier' (0x1ef510b68) to 'SimplePersistenceIdentifierTest.Computer' (0x1025884e0). I was surprised to find zero hit when Googling "Could not cast value of type 'SwiftData.PersistentIdentifier'". Some things to note: Calling teacher.computers?.append(computer) instead of computer.teacher = teacher results in the same error. It only happens when Teacher inherits Person. It only happens if modelContext.save() is called both times. It works if the first modelContext.save() is commented out. If the second modelContext.save()is commented out, the error occurs the second time the model context is saved (whether explicitly or implicitly). Keep in mind this is a super simple repro written to generate on demand the error I'm seeing in a normal app. In my app, modelContext.save() must be called in some places to update the UI immediately, sometimes resulting in the error seconds later when the model context is saved automatically. Not calling modelContext.save() doesn't appear to be an option. To be sure, I'm new to this ecosystem so I'd be thrilled if I've missed something obvious! Any thoughts are appreciated. import Foundation import SwiftData import SwiftUI struct ContentView: View { @Environment(\.modelContext) var modelContext var body: some View { VStack { Button("Do it") { let teacher = Teacher() let computer = Computer() modelContext.insert(teacher) modelContext.insert(computer) try! modelContext.save() computer.teacher = teacher try! modelContext.save() } } } } @Model class Computer { @Relationship(deleteRule: .nullify) var teacher: Teacher? init() {} } @Model class Person { init() {} } @available(iOS 26.0, macOS 26.0, *) @Model class Teacher: Person { @Relationship(deleteRule: .nullify, inverse: \Computer.teacher) public var computers: [Computer]? = [] override init() { super.init() } }
Replies
9
Boosts
2
Views
445
Activity
6d
Swift Data Recovery
Hi Writing an app in Swift on Xcode for my iPhone, all software is the latest version. If after making a minor change and re-building all the application data has disappeared, is there a way to see if it is still in the .modelContainer and just not showing up?
Replies
2
Boosts
0
Views
614
Activity
1w
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
266
Activity
1w
SwiftData Models and SortDesc. Only Work in One Swift File
Hey everyone, I found a possible SwiftData Release-only issue with nested sort descriptors on an optional relationship. In a minimal repro, sorting a @Query by a nested optional relationship key path like: SortDescriptor(\InvestigationPhotoAsset.imageAnalysis?.overallAestheticsScore, order: .reverse) works in Debug, but crashes at runtime in Release. The surprising part is that the crash depends on file layout: if the active SwiftData models and the sort logic are kept in the same Swift file, the app works if the same models are split into separate files, the Release build crashes, 'Debug' will also work The repro was reduced to just two SwiftData models: InvestigationPhotoAsset InvestigationImageAnalysis So this looks less like an app-modeling issue and more like a SwiftData/compiler/codegen issue related to nested sort metadata in optimized builds. If useful, I can also give you a slightly more formal version with a title and code snippet block. Please check out the code example here Has anyone faced something similar? Bug is reported as FB22173905
Replies
4
Boosts
0
Views
236
Activity
1w
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
84
Activity
1w
Mac Assigning NSManagedObject to NSPersistentStore
Hello, I have a iOS app I was looking at porting to Mac. I'm having an issue with both the Mac (Designed for iPad) and Mac Catalyst Destinations. I can't test Mac due to too many build issues. I'm trying to assign a new NSManagedObject into a NSPersistentStore. let object = MyObject(context: context) context.assign(object, to: nsPersistentStore) This works fine for iOS/iOS Simulator/iPhone/iPad. But on the Mac it's crashing with FAULT: NSInvalidArgumentException: Can't assign an object to a store that does not contain the object's entity.; { Thread 1: "Can't assign an object to a store that does not contain the object's entity."
Replies
6
Boosts
0
Views
243
Activity
1w
Missing demo project
Hi forum! I’m currently following a series of videos about SwiftData. In the WWDC23 Build an app with SwiftData video, it mentions that you can follow up with a demo project. However, I’m encountering an issue (at least in my case) where there’s no link on the entire page to download the project. I can download the video and other resources (even using the Developer’s App), but there’s no link for the project. Does anyone else face this issue? Is it possible that the project has been removed? I’m using my developer (single user) account, by the way. Any guidance would be greatly appreciated!
Replies
1
Boosts
0
Views
305
Activity
1w
Help Rescuing SwiftData Schema with Non-Optional Transformables
I currently have a schema in production (cloudKit and local files) containing non-optional transformable values, e.g. @Attribute(.transformable(by: TestTransformer.self)) var number: TestTransformable = TestTransformable.init(value: 100) Unfortunately, this is preventing any migration from succeeding (documented at length in FB22151570). Briefly summarized, any migration from a Schema containing non-optional transformable values fails between willMigrate and didMigrate with the error "Can't find model for source store". This occurs for all migrations, including lightweight with a migration plan, lightweight without a plan, and custom migrations. Worst of all, this also prevents migration to optional transformable values, or the elimination of the transformable value entirely, leaving us completely stuck. (note: optional transformable values only work when they have a default value set to nil, otherwise even these have issues migrating) We already have features being blocked by this issue, and would like to preserve user-data while restoring our ability to move forwards with database. Are there any known workarounds for using SwiftData (+CloudKit) when schema migration is non-operational?
Replies
2
Boosts
0
Views
124
Activity
2w
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.2k
Activity
2w
Core data destroyPersistentStore, not working for some
Hi all I have a problem with core data, where when a new user login that is different from the previous user i delete all of core data by using "destroyPersistentStore". Then i recreate the persistent store, this works when i am testing. When it does not work for one of my users when she test. I am not sure why this should not work, i have added the code i use to destroy the persistent store below. This code is run after login but before the view changes away from my login view. // Retrieves the shared `AppDelegate` instance guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return } appDelegate.destroyDataSyncBackground() // Get a reference to a NSPersistentStoreCoordinator let storeContainer = appDelegate.persistentContainer.persistentStoreCoordinator // Delete each existing persistent store for store in storeContainer.persistentStores { if let url = store.url { do { try storeContainer.destroyPersistentStore( at: url, ofType: store.type, options: nil ) } catch { print("Failed to deleted all") } } else { print("Failed to deleted all") } } // Re-create the persistent container appDelegate.persistentContainer = NSPersistentContainer( name: "CueToCue" // the name of // a .xcdatamodeld file ) // Calling loadPersistentStores will re-create the // persistent stores appDelegate.persistentContainer.loadPersistentStores { (store, error) in // Handle errors let description = NSPersistentStoreDescription() description.shouldMigrateStoreAutomatically = true description.shouldInferMappingModelAutomatically = true appDelegate.persistentContainer.persistentStoreDescriptions = [description] } // Reapply context configuration let viewContext = appDelegate.persistentContainer.viewContext viewContext.automaticallyMergesChangesFromParent = true viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy do { try viewContext.save() appDelegate.recreateDataSyncBackground() } catch { print("Debug: saving delete all failed.") } } The function "destroyDataSyncBackground" just set the my sync class to nil so stop any changes to core data while the code is running. The function "recreateDataSyncBackground" recreate the sync class so fetch, post and patch requests is made again.
Replies
3
Boosts
0
Views
119
Activity
2w
Sharing all container content
I've understood that SwiftData is not abled to share the whole content of a cloudkit database. So I'm trying to rewrite everything. Does someone knows id Sharing is coming on SwiftData at WWDC 26? Anyway, can someone can point me an example a a configured coredata stack that share all its content with other icloud users (with sharing pane and accept invitation code). At this step, on the owner side, I see some data in the default zone of my private container but nothing is visible on the shared zone. Maybe I don't understand where and when I should check shared data in cloudkit console. Need Help also here. See below by configuration stack: // Core Data container public lazy var container: NSPersistentContainer = { switch delegate.usage() { case .preview : return previewContainer() case .local : return localContainer() case .cloudKit : return cloudKitContainer() } }() private func cloudKitContainer() -> NSPersistentContainer { let modelURL = delegate.modelURL() let modelName = modelURL.deletingPathExtension().lastPathComponent guard let model = NSManagedObjectModel(contentsOf: modelURL) else { fatalError("Could not load Core Data model from \(modelURL)") } let container = NSPersistentCloudKitContainer( name: modelName, managedObjectModel: model ) let groupIdentifier = AppManager.shared.groupIdentifier guard let appGroupURL = FileManager.default.containerURL ( forSecurityApplicationGroupIdentifier: groupIdentifier ) else { fatalError("App Group not found: \(groupIdentifier)") } // MARK: - Private Store Configuration let privateStoreURL = appGroupURL.appendingPathComponent("\(modelName).sqlite") let privateStoreDescription = NSPersistentStoreDescription(url: privateStoreURL) // Persistent history tracking (MANDATORY) privateStoreDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) privateStoreDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) // CloudKit options for private database // Core Data automatically uses the default zone: com.apple.coredata.cloudkit.zone let privateCloudKitOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: delegate.cloudKitIdentifier()) privateCloudKitOptions.databaseScope = .private privateStoreDescription.cloudKitContainerOptions = privateCloudKitOptions // MARK: - Shared Store Configuration guard let sharedStoreDescription = privateStoreDescription.copy() as? NSPersistentStoreDescription else { fatalError("Create shareDesc error") } // The shared store receives zones that others share with us via CloudKit's shared database sharedStoreDescription.url = appGroupURL.appendingPathComponent("\(modelName)-shared.sqlite") // Persistent history tracking (MANDATORY) sharedStoreDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) sharedStoreDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) // CloudKit options for shared database // This syncs data from CloudKit shared zones when we accept share invitations let sharedCloudKitOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: delegate.cloudKitIdentifier()) sharedCloudKitOptions.databaseScope = .shared sharedStoreDescription.cloudKitContainerOptions = sharedCloudKitOptions // Configure both stores // Private store: com.apple.coredata.cloudkit.zone in private database // Shared store: Receives shared zones we're invited to container.persistentStoreDescriptions = [privateStoreDescription, sharedStoreDescription] container.loadPersistentStores { storeDescription, error in if let error = error as NSError? { fatalError("DB init error:\(error.localizedDescription)") } else if let cloudKitContiainerOptions = storeDescription.cloudKitContainerOptions { switch cloudKitContiainerOptions.databaseScope { case .private: self._privatePersistentStore = container.persistentStoreCoordinator.persistentStore(for: privateStoreDescription.url!) case .shared: self._sharedPersistentStore = container.persistentStoreCoordinator.persistentStore(for: sharedStoreDescription.url!) default: break } } let scope = storeDescription.cloudKitContainerOptions?.databaseScope == .shared ? "shared" : "private" print("✅ \(scope) store loaded at: \(storeDescription.url?.path ?? "unknown")") } // Auto-merge container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy do { try container.viewContext.setQueryGenerationFrom(.current) } catch { fatalError("Fail to pin viewContext to the current generation:\(error)") } return container }
Replies
7
Boosts
0
Views
238
Activity
2w
CloudKit references — is this a forward reference or a back reference?
I'm trying to understand the terminology around forward vs backward references in CloudKit. Say I have two record types: User LeaderboardScore (a score belongs to a user) The score record stores a user reference: score["user"] = CKRecord.Reference( recordID: userRecordID, action: .deleteSelf ) So: LeaderboardScore → User The user record does not store any references to scores From a data-model perspective: Is this considered a forward reference (child → parent)? Or a back reference, since the score is "pointing back" to its owner? My use case is having leaderboard in my app and so i have created a user table to store all the users and a score table for saving the scores of each user of the app.
Replies
4
Boosts
0
Views
170
Activity
2w
CloudKit Sync Stalls During Initial Large Data Hydration on New Device (SwiftData Local-First Architecture)
Hi everyone, I’m facing an issue with CloudKit sync getting stuck during initial device migration in my SwiftData-based app. The app follows a local-first architecture using SwiftData + CloudKit sync, and works correctly for: ✔ Incremental sync ✔ Bi-directional updates ✔ Small datasets However, when onboarding a new device with large historical data, sync becomes extremely slow or appears stuck. Even after two hours data is not fully synced. ~6900 Transactions 🚨 Problem When installing the app on a new iPhone and enabling iCloud sync: • Initial hydration starts • A small amount of data syncs • Then sync stalls indefinitely Observed behaviour: • iPhone → Mac sync works (new changes sync back) • Mac → iPhone large historical migration gets stuck • Reinstalling app / clearing container does not resolve issue • Sync never completes full migration This gives the impression that: CloudKit is trickling data but not progressing after a certain threshold. The architecture is: • SwiftData local store • Manual CloudKit sync layer • Local-first persistence • Background push/pull sync So I understand: ✔ Conflict resolution is custom ✔ Initial import may not be optimized by default But I expected CloudKit to eventually deliver all records. Instead, the new device remains permanently in a “partial state”. ⸻ 🔍 Observations • No fatal CloudKit errors • No rate-limit errors • No quota issues • iCloud is available • Sync state remains “Ready” • Hydration remains “mostlyReady” Meaning: CloudKit does not report failure — but data transfer halts. ⸻ 🤔 Questions Would appreciate guidance on: Is CloudKit designed to support large initial dataset migration via manual sync layers? Or is this a known limitation vs NSPersistentCloudKitContainer? ⸻ Does CloudKit internally throttle historical record fetches? Could it silently stall without error when record volume is high? ⸻ Is there any recommended strategy for: • Bulk initial migration • Progressive hydration • Forcing forward sync progress ⸻ Should initial migration be handled outside CloudKit (e.g. via file transfer / backup restore) before enabling sync? ⸻ 🎯 Goal I want to support: • Large historical onboarding • Multi-device sync • User-visible progress Without forcing migration to Core Data. ⸻ 🙏 Any advice on: • Best practices • Debugging approach • CloudKit behavior in such scenarios would be greatly appreciated. Thank you!
Replies
1
Boosts
0
Views
138
Activity
3w
SwiftData Unidirectional Relationships
Hi everyone I would like to achieve having unidirectional relationships in my SwiftData project (which I believe is possible: https://developer.apple.com/documentation/updates/swiftdata?changes=_9) but I'm afraid I'm struggling to overcome the errors I'm experiencing. For example, I have the following models: @Model final class Quota { @Attribute(.unique) var id: UUID var allowance: Int @Relationship(inverse: nil) var fish: Fish init(id: UUID = UUID(), fish: Fish, allowance: Int) { self.id = id self.fish = fish self.allowance = allowance } } @Model final class Fish { @Attribute(.unique) var id: Int var name: String init(id: Int, name: String) { self.id = id, self.name = name } } However, when I attempt to save a quota as so: let quota: Quota = .init(fish: Fish(id: 2, name: "Salmon"), allowance: 50) modelContext?.insert(quota) try save() I keep getting the following error: SwiftData.DefaultStore save failed with error: Error Domain=NSCocoaErrorDomain Code=1570 "%{PROPERTY}@ is a required value." UserInfo={NSValidationErrorObject=<NSManagedObject: 0x600002217390> (entity: Fish; id: 0x83319d001151328d <x-coredata://C76A2A64-146E-432F-A565-319B5A2F23F5/Fish/p12>; data: { id = nil; }), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=id, NSValidationErrorValue=null} %{PROPERTY}@ is a required value. However, if I set up Quota and Fish with an inverse relationship then the data saves as expected, so I'm a little confused. Is there anyone out there who can provide some guidance as to why I'm seeing this error when I try to save a record in SwiftData with no inverse relationship? I do fully understand about unidirectional vs bidirectional relationships but I have a scenario where I need the relationship to be unidirectional. Also, as a side note, the Fish record already exists in my database, but if I delete it and try to save the record I still see this error. Thank you so much in advance for any help.
Replies
1
Boosts
0
Views
175
Activity
3w
iCloud Account Signing Out
I have several macOS applications that use CloudKit. I need to test and finds out what happens when the user signs out of their iCloud account. That's because the application may lose data after signing out and then signing in again. Every time I do that, it'll take 15, 20 minutes... I don't time it, but it takes quite a gigantic time to sign out as the spinner keeps rolling. Why does it take so long to just sign out? This sign out effect is untestable because it takes a long time to sign out of an iCloud account and then make changes to the code and then test again. In case you need to know, my system version is Sequoia 15.7.
Replies
2
Boosts
0
Views
135
Activity
3w
Importing Data into SwiftData in the Background Using ModelActor and @Query
I have an app with fairly typical requirements - I need to insert some data (in my case from the network but could be anything) and I want to do it in the background to keep the UI responsive. I'm using SwiftData. I've created a ModelActor that does the importing and using the debugger I can confirm that the data is indeed being inserted. On the UI side, I'm using @Query and a SwiftUI List to display the data but what I am seeing is that @Query is not updating as the data is being inserted. I have to quit and re-launch the app in order for the data to appear, almost like the context running the UI isn't communicating with the context in the ModelActor. I've included a barebones sample project. To reproduce the issue, tap the 'Background Insert' button. You'll see logs that show items being inserted but the UI is not showing any data. I've tested on the just released iOS 18b3 seed (22A5307f). The sample project is here: https://hanchor.s3.amazonaws.com/misc/SwiftDataBackgroundV2.zip
Replies
24
Boosts
13
Views
6.3k
Activity
3w