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

CK WebServices getting 500 Internal Error
Hello, If I want to modify records in my public database, this works fine. However, if I change from public to private in the requesturl, I get the response: "500 - Internal Error". According to the CK WebService Reference, it is possible to access the private database. Could someone explain to me if it is really an internal error and if it could be fixed by Apple, since I would like to access my own private database with the server-to-server key. Thanks in advance.
1
0
66
3w
CoreData not documented UserInfo Notification
Hello, the last days I was trying to solve a bug in my Unit Tests related to the CoreData "NSManagedObjectContextObjectsDidChange" Notification. Im using some kind of Notification handler to save and abstract that for the UI and while the tests are running this notification was triggered with objects that doesn't exists anymore, which has resulted in a crash. After some debugging I have detected, that the objects in here are really old. The objects here was from few tests ago, where a Merge Conflict happened. In the meantime there was a plenty of resets and deletes of the whole db. I have also seen that the bad notification is the first in the stack trace of the main thread, which is in my opinion also not usual. So the real question is: The only difference what I have found for the bad notification to the real notification, was the existence of the key "NSObjectsChangedByMergeChangesKey" in the UserInfo dictionary of the ObjectsDidChange Notification. But this key is nowhere found in the documentation of Apple. Also the search engines does not produce any result. So what is this key and when is this key contained in this notification and when not? Maybe if I understand this, it helps me to understand the overall issue ...
3
0
118
3w
SwiftData Versioning with Top-Level Models
If an app is using top-level models, meaning they exist outside the VersionedSchema enum, is it safe to keep them outside of the VersionedSchema enum and use a migration plan for simple migrations. Moving the models within the VersionedSchema enum I believe would change the identity of the models and result in data being lost, although correct me if I'm wrong in that statement. The need presently is just to add another variable to the model and then set that variable within the init function: var updateId = UUID() The app is presently in TestFlight although I'd like to preserve data for users that are currently using the app. The data within SwiftData is synchronized with CloudKit and so I'd also like to avoid any impact to synchronization. Any thoughts on this would be greatly appreciated.
1
0
142
3w
Strange behavior with 100k+ records in NSPersistentCloudKitContainer
I have been using the basic NSPersistentContainer with 100k+ records for a while now with no issues. The database size can fluctuate a bit but on average it takes up about 22mb on device. When I switch the container to NSPersistentCloudKitContainer, I see a massive increase in size to ~150mb initially. As the sync engine uploads records to iCloud it has ballooned to over 600mb on device. On top of that, the user's iCloud usage in settings reports that it takes up 1.7gb in the cloud. I understand new tables are added and history tracking is enabled but the size increase seems a bit drastic. I'm not sure how we got from 22mb to 1.7gb with the exact same data. A few other things that are important to note: I import all the 100k+ records at once when testing the different containers. At the time of the initial import there is only 1 relation (an import group record) that all the records are attached to. I save the background context only once after all the records and the import group have been made and added to the context. After the initial import, some of these records may have a few new relations added to them over time. I suppose this could be causing some of the size increase, but its only about 20,000 records that are updated. None of the records include files/ large binary data. Most of the attributes are encrypted. I'm syncing to the dev iCloud environment. When I do make a change to a single attribute in a record, CloudKit reports that every attribute has been modified (not sure if this is normal or not ) Also, When syncing to a new device, the sync can take hours - days. I'm guessing it's having to sync both the new records and the changes, but it exponentially gets slower as more records are downloaded. The console will show syncing activity, but new records are being added at a slower rate as more records are added. After about 50k records, it grinds to a halt and while the console still shows sync activity, only about 100 records are added every hour. All this to say i'm very confused where these issues are coming from. I'm sure its a combination of how i've setup my code and the vast record count, record history, etc. If anyone has any ideas it would be much appreciated.
3
1
659
Nov ’25
A crash occurs when fetching history when Model has preserveValueOnDeletion attribute and using inheritance
Hello, In our app, we’ve modeled our schema using inheritance introduced in iOS 26.0, and we’re implementing SwiftData History to re-fetch models only when necessary. @Model public class Transaction { @Attribute(.preserveValueOnDeletion) public var date: Date = Date() public var amount: Double = 0 public var memo: String? } @Model public final class Spending: Transaction { public var installmentIndex: Int = 1 public var installment: Int = 1 public var installmentID: UUID? } If data has been deleted from database, we need to check a date property to determine whether to re-fetch datas. To do this, we added the preserveValueOnDeletion attribute to date property so we could retrieve it from the History tombstone value. However, after adding this attribute, a crash occurs. There is a console log Could not cast value of type 'Swift.ReferenceWritableKeyPath<Shared.ModelSchemaV5.Transaction, Foundation.Date>' (0x106bf8328) to 'Swift.PartialKeyPath<Shared.ModelSchemaV5.Spending>' (0x1094f21d8). and error log attached StrictMoneyChecking-2025-11-07-105108.txt I also tried this in the recent SampleTrip app, and fetching all history after a deletion causes the same crash. Is this issue currently being worked on or under investigation?
1
0
253
Nov ’25
Correct SwiftData Concurrency Logic for UI and Extensions
Hi everyone, I'm looking for the correct architectural guidance for my SwiftData implementation. In my Swift project, I have dedicated async functions for adding, editing, and deleting each of my four models. I created these functions specifically to run certain logic whenever these operations occur. Since these functions are asynchronous, I call them from the UI (e.g., from a button press) by wrapping them in a Task. I've gone through three different approaches and am now stuck. Approach 1: @MainActor Functions Initially, my functions were marked with @MainActor and worked on the main ModelContext. This worked perfectly until I added support for App Intents and Widgets, which caused the app to crash with data race errors. Approach 2: Passing ModelContext as a Parameter To solve the crashes, I decided to have each function receive a ModelContext as a parameter. My SwiftUI views passed the main context (which they get from @Environment(\.modelContext)), while the App Intents and Widgets created and passed in their own private context. However, this approach still caused the app to crash sometimes due to data race errors, especially during actions triggered from the main UI. Approach 3: Creating a New Context in Each Function I moved to a third approach where each function creates its own ModelContext to work on. This has successfully stopped all crashes. However, now the UI actions don't always react or update. For example, when an object is added, deleted, or edited, the change isn't reflected in the UI. I suspect this is because the main context (driving the UI) hasn't been updated yet, or because the async function hasn't finished its work. My Question I'm not sure what to do or what the correct logic should be. How should I structure my data operations to support the main UI, Widgets, and App Intents without causing crashes or UI update failures? Here is the relevant code using my third (and current) approach. I've shortened the helper functions for brevity. // MARK: - SwiftData Operations extension DatabaseManager { /// Creates a new assignment and saves it to the database. public func createAssignment( name: String, deadline: Date, notes: AttributedString, forCourseID courseID: UUID, /*...other params...*/ ) async throws -> AssignmentModel { do { let context = ModelContext(container) guard let course = findCourse(byID: courseID, in: context) else { throw DatabaseManagerError.itemNotFound } let newAssignment = AssignmentModel( name: name, deadline: deadline, notes: notes, course: course, /*...other properties...*/ ) context.insert(newAssignment) try context.save() // Schedule notifications and add to calendar _ = try? await scheduleReminder(for: newAssignment) newAssignment.calendarEventIDs = await CalendarManager.shared.addEventToCalendar(for: newAssignment) try context.save() await MainActor.run { WidgetCenter.shared.reloadTimelines(ofKind: "AppWidget") } return newAssignment } catch { throw DatabaseManagerError.saveFailed } } /// Finds a specific course by its ID in a given context. public func findCourse(byID id: UUID, in context: ModelContext) -> CourseModel? { let predicate = #Predicate<CourseModel> { $0.id == id } let fetchDescriptor = FetchDescriptor<CourseModel>(predicate: predicate) return try? context.fetch(fetchDescriptor).first } } // MARK: - Helper Functions (Implementations omitted for brevity) /// Schedules a local user notification for an event. func scheduleReminder(for assignment: AssignmentModel) async throws -> String { // ... Full implementation to create and schedule a UNNotificationRequest return UUID().uuidString } /// Creates a new event in the user's selected calendars. extension CalendarManager { func addEventToCalendar(for assignment: AssignmentModel) async -> [String] { // ... Full implementation to create and save an EKEvent return [UUID().uuidString] } } Thank you for your help.
5
0
187
Nov ’25
Is that possible to update ModelContainer?
Here is what I thought I want to give each user a unique container, when the user login or register, the user could isolate their data in specific container. I shared the container in a singleton actor, I found it's possible to update the container in that actor. But I think it won't affect the modelContext which is in the Environment. Does SwiftData allow me or recommend to do that?
4
0
210
Nov ’25
iOS 26.1 and SwiftData: Can't reuse store?
I have one target building and filling the SwiftData store and then copying the same store file to another target of the app to use the contents. That worked fine from iOS 17 to iOS 26.0.1 Under iOS 26.1 I am getting following error: CoreData: error: This store file was previously used on a build with Persistence-1522 but is now running on a build with Persistence-1518. file:///Users/xxx/Library/Developer/CoreSimulator/Devices/0FE92EA2-57FA-4A5E-ABD0-DAB4DABC3E02/data/Containers/Data/Application/B44D3256-9B09-4A60-94E2-C5F11A6519E7/Documents/default.store What does it mean and how to get back to working app under iOS 26.1?
1
0
194
Nov ’25
SwiftData and CloudKit Issues
Hi, I'm using SwiftData in my app, and I want to sent data to iCloud with CloudKit, but I found that If the user turns off my App iCloud sync function in the settings App, the local data will also be deleted. A better way is maintaining the local data, just don't connect to iCloud.How should I do that? I need guidance!!! I'm just getting started with CloudKit And I would be appreciated!
1
0
162
Nov ’25
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.1k
Nov ’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
146
Nov ’25
SwiftData Migration: Objects Created in Custom Migration Aren't Persisted or Queryable (Repost)
I'm experiencing a critical issue with SwiftData custom migrations where objects created during migration appear to be inserted successfully but aren't persisted or found by queries after migration completes. The migration logs show objects being created, but subsequent queries return zero results. I'm migrating from schema version V2 to V2_5, which involves: Renaming Person class to GroupData Keeping the same data structure but changing the class name while keeping the old class. Using a custom migration stage to copy data from old to new schema Below is an extract of my two schema and migration plan: Environment: Xcode 16.0, iOS 18.0, Swift 6.0 SchemaV2 enum LinkMapV2: VersionedSchema { static let versionIdentifier: Schema.Version = .init(2, 0, 0) static var models: [any PersistentModel.Type] { [AnnotationData.self, Person.self, History.self] } @Model final class Person { @Attribute(.unique) var id: UUID var name: String var photo: String var requirement: String var statue: Bool var annotationId: UUID? var number: Int = 0 init(id: UUID = UUID(), name: String = "", photo: String = "", requirement: String = "", status: Bool = false, annotationId: UUID? = nil, number: Int = 0) { self.id = id self.name = name self.photo = photo self.requirement = requirement self.statue = status self.annotationId = annotationId self.number = number } } } Schema V2_5 static let versionIdentifier: Schema.Version = .init(2, 5, 0) static var models: [any PersistentModel.Type] { [AnnotationData.self, Person.self, GroupData.self, History.self] } // Keep the old Person model for migration @Model final class Person { @Attribute(.unique) var id: UUID var name: String var photo: String var requirement: String var statue: Bool var annotationId: UUID? var number: Int = 0 init(id: UUID = UUID(), name: String = "", photo: String = "", requirement: String = "", status: Bool = false, annotationId: UUID? = nil, number: Int = 0) { self.id = id self.name = name self.photo = photo self.requirement = requirement self.statue = status self.annotationId = annotationId self.number = number } } // Add the new GroupData model that mirrors Person @Model final class GroupData { @Attribute(.unique) var id: UUID var name: String var photo: String var requirement: String var status: Bool var annotationId: UUID? var number: Int = 0 init(id: UUID = UUID(), name: String = "", photo: String = "", requirement: String = "", status: Bool = false, annotationId: UUID? = nil, number: Int = 0) { self.id = id self.name = name self.photo = photo self.requirement = requirement self.status = status self.annotationId = annotationId self.number = number } } } Migration Plan static let migrationV2toV2_5 = MigrationStage.custom( fromVersion: LinkMapV2.self, toVersion: LinkMapV2_5.self, willMigrate: { context in do { let persons = try context.fetch(FetchDescriptor<LinkMapV2.Person>()) print("=== MIGRATION STARTED ===") print("Found \(persons.count) Person objects to migrate") guard !persons.isEmpty else { print("No Person data requires migration") return } for person in persons { print("Migrating Person: '\(person.name)' with ID: \(person.id)") let newGroup = LinkMapV2_5.GroupData( id: person.id, // Keep the same ID name: person.name, photo: person.photo, requirement: person.requirement, status: person.statue, annotationId: person.annotationId, number: person.number ) context.insert(newGroup) print("Inserted new GroupData: '\(newGroup.name)'") // Don't delete the old Person yet to avoid issues // context.delete(person) } try context.save() print("=== MIGRATION COMPLETED ===") print("Successfully migrated \(persons.count) Person objects to GroupData") } catch { print("=== MIGRATION ERROR ===") print("Migration failed with error: \(error)") } }, didMigrate: { context in do { // Verify migration in didMigrate phase let groups = try context.fetch(FetchDescriptor<LinkMapV2_5.GroupData>()) let oldPersons = try context.fetch(FetchDescriptor<LinkMapV2_5.Person>()) print("=== MIGRATION VERIFICATION ===") print("New GroupData count: \(groups.count)") print("Remaining Person count: \(oldPersons.count)") // Now delete the old Person objects for person in oldPersons { context.delete(person) } if !oldPersons.isEmpty { try context.save() print("Cleaned up \(oldPersons.count) old Person objects") } // Print all migrated groups for debugging for group in groups { print("Migrated Group: '\(group.name)', Status: \(group.status), Number: \(group.number)") } } catch { print("Migration verification error: \(error)") } } ) And I've attached console output below: Console Output
1
0
111
Nov ’25
SwiftData Migration: Objects Created in Custom Migration Aren't Persisted or Queryable
Description: I'm experiencing a critical issue with SwiftData custom migrations where objects created during migration appear to be inserted successfully but aren't persisted or found by queries after migration completes. The migration logs show objects being created, but subsequent queries return zero results. Problem Details: I'm migrating from schema version V2 to V3, which involves: Renaming Person class to GroupData Keeping the same data structure but changing the class name Using a custom migration stage to copy data from old to new schema Migration Code: swift static let migrationV2toV3 = MigrationStage.custom( fromVersion: LinkMapV2.self, toVersion: LinkMapV3.self, willMigrate: { context in do { let persons = try context.fetch(FetchDescriptor<LinkMapV2.Person>()) print("Found (persons.count) Person objects to migrate") // ✅ Shows 11 objects for person in persons { let newGroup = LinkMapV3.GroupData( id: person.id, // Same UUID name: person.name, // ... other properties ) context.insert(newGroup) print("Inserted GroupData: '\(newGroup.name)'") // ✅ Confirms insertion } try context.save() // ✅ No error thrown print("Successfully migrated \(persons.count) objects") // ✅ Confirms save } catch { print("Migration error: \(error)") } }, didMigrate: { context in do { let groups = try context.fetch(FetchDescriptor<LinkMapV3.GroupData>()) print("Final GroupData count: \(groups.count)") // ❌ Shows 0 objects! } catch { print("Verification error: \(error)") } } ) Console Output: text === MIGRATION STARTED === Found 11 Person objects to migrate Migrating Person: 'Riverside of pipewall' with ID: 7A08C633-4467-4F52-AF0B-579545BA88D0 Inserted new GroupData: 'Riverside of pipewall' ... (all 11 objects processed) ... === MIGRATION COMPLETED === Successfully migrated 11 Person objects to GroupData === MIGRATION VERIFICATION === New GroupData count: 0 // ❌ PROBLEM: No objects found! What I've Tried: Multiple context approaches: Using the provided migration context Creating a new background context with ModelContext(context.container) Using context.performAndWait for thread safety Different save strategies: Calling try context.save() after insertions Letting SwiftData handle saving automatically Multiple save calls at different points Verification methods: Checking in didMigrate closure Checking in app's ContentView after migration completes Using both @Query and manual FetchDescriptor Schema variations: Direct V2→V3 migration Intermediate V2.5 schema with both classes Lightweight migration with @Attribute(originalName:) Current Behavior: Migration runs without errors Objects appear to be inserted successfully context.save() completes without throwing errors But queries in didMigrate and post-migration return empty results The objects seem to exist in a temporary state that doesn't persist Expected Behavior: Objects created during migration should be persisted and queryable Post-migration queries should return the migrated objects Data should be available in the main app after migration completes Environment: Xcode 16.0+ iOS 18.0+ SwiftData Swift 6.0+ Key Questions: Is there a specific way migration contexts should be handled for data to persist? Are there known issues with object persistence in custom migrations? Should we be using a different approach for class renaming migrations? Is there a way to verify that objects are actually being written to the persistent store? The migration appears to work perfectly until the verification step, where all created objects seem to vanish. Any guidance would be greatly appreciated! Additional Context from my investigation: I've noticed these warning messages during migration that might be relevant: text SwiftData.ModelContext: Unbinding from the main queue. This context was instantiated on the main queue but is being used off it. error: Persistent History (76) has to be truncated due to the following entities being removed: (Person) This suggests there might be threading or context lifecycle issues affecting persistence. Let me know if you need any additional information about my setup or migration configuration!
1
0
88
Nov ’25
SwiftData: Crash when deleting from model, but only in prod
I'm testing my app before releasing to testers, and my app (both macOS and iOS) is crashing when I perform one operation, but only in the production build. I have data that loads from a remote source, and can be periodically updated. There is an option to delete all of that data from the iCloud data store, unless the user has modified a record. Each table has a flag to indicate that (userEdited). Here's the function that is crashing: func deleteCommonData<T:PersistentModel & SDBuddyModel>(_ type: T.Type) throws { try modelContext.delete(model: T.self, where: #Predicate<T> { !$0.userEdited }) } Here's one of the calls that results in a crash: try modelManager.deleteCommonData(Link.self) Here's the error from iOS Console: SwiftData/DataUtilities.swift:85: Fatal error: Couldn't find \Link.<computed 0x0000000104b9d208 (Bool)> on Link with fields [SwiftData.Schema.PropertyMetadata(name: "id", keypath: \Link.<computed 0x0000000104b09b44 (String)>, defaultValue: Optional("54EC6602-CA7C-4EC7-AC06-16E7F2E22DE7"), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "name", keypath: \Link.<computed 0x0000000104b09b84 (String)>, defaultValue: Optional(""), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "url", keypath: \Link.<computed 0x0000000104b09bc4 (String)>, defaultValue: Optional(""), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "desc", keypath: \Link.<computed 0x0000000104b09c04 (String)>, defaultValue: Optional(""), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "userEdited", keypath: \Link.<computed 0x0000000104b09664 (Bool)>, defaultValue: Optional(false), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "modified", keypath: \Link.<computed 0x0000000104b09c44 (Date)>, defaultVal<…> Here's a fragment of the crash log: Exception Type: EXC_BREAKPOINT (SIGTRAP) Exception Codes: 0x0000000000000001, 0x000000019373222c Termination Reason: Namespace SIGNAL, Code 5, Trace/BPT trap: 5 Terminating Process: exc handler [80543] Thread 0 Crashed: 0 libswiftCore.dylib 0x19373222c _assertionFailure(_:_:file:line:flags:) + 176 1 SwiftData 0x22a222160 0x22a1ad000 + 479584 2 SwiftData 0x22a2709c0 0x22a1ad000 + 801216 3 SwiftData 0x22a221b08 0x22a1ad000 + 477960 4 SwiftData 0x22a27b0ec 0x22a1ad000 + 844012 5 SwiftData 0x22a27b084 0x22a1ad000 + 843908 6 SwiftData 0x22a28182c 0x22a1ad000 + 870444 7 SwiftData 0x22a2809e8 0x22a1ad000 + 866792 8 SwiftData 0x22a285204 0x22a1ad000 + 885252 9 SwiftData 0x22a281c7c 0x22a1ad000 + 871548 10 SwiftData 0x22a27cf6c 0x22a1ad000 + 851820 11 SwiftData 0x22a27cc48 0x22a1ad000 + 851016 12 SwiftData 0x22a27a6b0 0x22a1ad000 + 841392 13 SwiftData 0x22a285b2c 0x22a1ad000 + 887596 14 SwiftData 0x22a285a10 0x22a1ad000 + 887312 15 SwiftData 0x22a285bcc 0x22a1ad000 + 887756 16 SwiftData 0x22a27cf6c 0x22a1ad000 + 851820 17 SwiftData 0x22a27cc48 0x22a1ad000 + 851016 18 SwiftData 0x22a27a6b0 0x22a1ad000 + 841392 19 SwiftData 0x22a27c0d8 0x22a1ad000 + 848088 20 SwiftData 0x22a27a654 0x22a1ad000 + 841300 21 SwiftData 0x22a1be548 0x22a1ad000 + 70984 22 SwiftData 0x22a1cfd64 0x22a1ad000 + 142692 23 SwiftData 0x22a1b9618 0x22a1ad000 + 50712 24 SwiftData 0x22a1d2e8c 0x22a1ad000 + 155276 25 CoreData 0x187fbb568 thunk for @callee_guaranteed () -> (@out A, @error @owned Error) + 28 26 CoreData 0x187fc2300 partial apply for thunk for @callee_guaranteed () -> (@out A, @error @owned Error) + 24 27 CoreData 0x187fc19c4 closure #1 in closure #1 in NSManagedObjectContext._rethrowsHelper_performAndWait<A>(fn:execute:rescue:) + 192 28 CoreData 0x187fbbda8 thunk for @callee_guaranteed @Sendable () -> () + 28 29 CoreData 0x187fbbdd0 thunk for @escaping @callee_guaranteed @Sendable () -> () + 28 30 CoreData 0x187f663fc developerSubmittedBlockToNSManagedObjectContextPerform + 252 31 libdispatch.dylib 0x180336ac4 _dispatch_client_callout + 16 32 libdispatch.dylib 0x18032c940 _dispatch_lane_barrier_sync_invoke_and_complete + 56 33 CoreData 0x187fd7290 -[NSManagedObjectContext performBlockAndWait:] + 364 34 CoreData 0x187fc1fb8 NSManagedObjectContext.performAndWait<A>(_:) + 544 35 SwiftData 0x22a1b877c 0x22a1ad000 + 46972 36 SwiftData 0x22a1be2a8 0x22a1ad000 + 70312 37 SwiftData 0x22a1c0e34 0x22a1ad000 + 81460 38 SwiftData 0x22a23ea94 0x22a1ad000 + 596628 39 SwiftData 0x22a256828 0x22a1ad000 + 694312 40 Sourdough Buddy 0x104e5dc98 specialized ModelManager.deleteCommonData<A>(_:) + 144 (ModelManager.swift:128) [inlined] 41 Sourdough Buddy 0x104e5dc98 closure #1 in SettingsView.clearStarterData.getter + 876 (SettingsView.swift:243) It works if I do the following instead: try modelContext.delete(model: Link.self, where: #Predicate { !$0.userEdited }) Why would the func call work in development, but crash in production? And why does doing the more verbose way work instead? I think this is a bug. Thanks
3
1
99
Oct ’25
Swift Data Predicate Evaluation Crashes in Release Build When Generics Used
I'm using Swift Data for an app that requires iOS 18. All of my models conform to a protocol that guarantees they have a 'serverID' String variable. I wrote a function that would allow me to pass in a serverID String and have it fetch the model object that matched. Because I am lazy and don't like writing the same functions over and over, I used a Self reference so that all of my conforming models get this static function. Imagine my model is called "WhatsNew". Here's some code defining the protocol and the fetching function. protocol RemotelyFetchable: PersistentModel { var serverID: String { get } } extension WhatsNew: RemotelyFetchable {} extension RemotelyFetchable { static func fetchOne(withServerID identifier: String, inContext modelContext: ModelContext) -> Self? { var fetchDescriptor = FetchDescriptor<Self>() fetchDescriptor.predicate = #Predicate<Self> { $0.serverID == identifier } do { let allModels = try modelContext.fetch(fetchDescriptor) return allModels.first } catch { return nil } } } Worked great! Or so I thought... I built this and happily ran a debug build in the Simulator and on devices for months while developing the initial version but when I went to go do a release build for TestFlight, that build reliably crashed on every device with a message like this: SwiftData/DataUtilities.swift:65: Fatal error: Couldn't find \WhatsNew. on WhatsNew with fields [SwiftData.Schema.PropertyMetadata(name: "serverID", keypath: \WhatsNew., defaultValue: nil, metadata: Optional(Attribute - name: , options: [unique], valueType: Any, defaultValue: nil, hashModifier: nil)), SwiftData.Schema.PropertyMetadata(name: "title", keypath: \WhatsNew., defaultValue: nil, metadata: nil), SwiftData.Schema.PropertyMetadata(name: "bulletPoints", keypath: \WhatsNew.)>, defaultValue: nil, metadata: nil), SwiftData.Schema.PropertyMetadata(name: "dateDescription", keypath: \WhatsNew., defaultValue: nil, metadata: nil), SwiftData.Schema.PropertyMetadata(name: "readAt", keypath: \WhatsNew.)>, defaultValue: nil, metadata: nil)] It seems (cannot confirm) that something in the release build optimization process is stripping out some metadata / something about these models that makes this predicate crash. Tested on iOS 18.0 and 18.1 beta. How can I resolve this? I have two dozen types that conform to this protocol. I could manually specialize this function for every type myself but... ugh.
2
2
1.4k
Oct ’25