SwiftData

RSS for tag

SwiftData is an all-new framework for managing data within your apps. Models are described using regular Swift code, without the need for custom editors.

Posts under SwiftData tag

189 Posts

Post

Replies

Boosts

Views

Activity

SwiftData Background Fetching?
Hi, I am experiencing main thread freezes from fetching on Main Actor. Attempting to move the function to a background thread, but whenever I reference the TestModel in a nonisolated context or in another model actor, I get this warning: Main actor-isolated conformance of 'TestModel' to 'PersistentModel' cannot be used in actor-isolated context; this is an error in the Swift 6 language mode Is there a way to do this correctly? Recreation, warning on line 13: class TestModel { var property: Bool = true init() {} } struct SendableTestModel: Sendable { let property: Bool } @ModelActor actor BackgroundActor { func fetch() throws -> [SendableTestModel] { try modelContext.fetch(FetchDescriptor<TestModel>()).map { SendableTestModel(property: $0.property) } } }
1
0
145
Jul ’25
Complex view structures are frustratingly too much work
The Java Swing and AWT MVC model made it easy to develop complex UIs with data interactions that were not described readily in a nested layer that SwiftUI demands. The implicit update model of SwiftUI greatly complicates development of applications that often requires nested components to have to know too much about other components and other structures than their own, because button events and other user interactions cannot readily alter state across layers. A button push on one component then has to be knowledgable about state in other components which have to have that state represented as @State or @Binding etc. and this causes all kinds of wiring to be spread all over the place rather than have a more centralized "state management function" that would be able to look at the world and synchronize the UIs state across changes. The fact that the compiler get's lost in the weeds when types and signatures don't match in deeper component structures doesn't help because it makes it doubly hard to do refactoring to raise and lower state management within the structure readily, because the compiler just cannot simply tell you that a function or constructor signature is no longer correct.
1
0
207
Jul ’25
Extending @Model with custom macros
I am trying to extend my PersistedModels like so: @Versioned(3) @Model class MyType { var name: String init() { name = "hello" } } but it seems that SwiftData's@Model macro is unable to read the properties added by my @Versioned macro. I have tried changing the order and it ignores them regardless. version is not added to schemaMetadata and version needs to be persisted. I was planning on using this approach to add multiple capabilities to my model types. Is this possible to do with macros? VersionedMacro /// A macro that automatically implements VersionedModel protocol public struct VersionedMacro: MemberMacro, ExtensionMacro { // Member macro to add the stored property directly to the type public static func expansion( of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] { guard let argumentList = node.arguments?.as(LabeledExprListSyntax.self), let firstArgument = argumentList.first?.expression else { throw MacroExpansionErrorMessage("@Versioned requires a version number, e.g. @Versioned(3)") } let versionValue = firstArgument.description.trimmingCharacters(in: .whitespaces) // Add the stored property with the version value return [ "public private(set) var version: Int = \(raw: versionValue)" ] } // Extension macro to add static property public static func expansion( of node: SwiftSyntax.AttributeSyntax, attachedTo declaration: some SwiftSyntax.DeclGroupSyntax, providingExtensionsOf type: some SwiftSyntax.TypeSyntaxProtocol, conformingTo protocols: [SwiftSyntax.TypeSyntax], in context: some SwiftSyntaxMacros.MacroExpansionContext ) throws -> [SwiftSyntax.ExtensionDeclSyntax] { guard let argumentList = node.arguments?.as(LabeledExprListSyntax.self), let firstArgument = argumentList.first?.expression else { throw MacroExpansionErrorMessage("@Versioned requires a version number, e.g. @Versioned(3)") } let versionValue = firstArgument.description.trimmingCharacters(in: .whitespaces) // We need to explicitly add the conformance in the extension let ext = try ExtensionDeclSyntax("extension \(type): VersionedModel {}") .with(\.memberBlock.members, MemberBlockItemListSyntax { MemberBlockItemSyntax(decl: DeclSyntax( "public static var version: Int { \(raw: versionValue) }" )) }) return [ext] } } VersionedModel public protocol VersionedModel: PersistentModel { /// The version of this particular instance var version: Int { get } /// The type's current version static var version: Int { get } } Macro Expansion:
1
0
421
Aug ’25
Mixing in-memory and persistent SwiftData containers in a Document-based App?
Hello, I'm trying to work on an iPadOS and macOS app that will rely on the document-based system to create some kind of orientation task to follow. Let say task1.myfile will be a check point regulation from NYC to SF and task2.myfile will be a visit as many key location as you can in SF. The file represent the specific landmark location and rules of the game. And once open, I will be able to read KML/GPS file to evaluate their score based with the current task. But opened GPS files does not have to be stored in the task file itself, it stay alongside. I wanted to use that scenario to experiment with SwiftData (I'm a long time CoreData user, I even wrote my own WebDAV based persistent store back in the day), and so, mix both on file and in memory persistent store, with distribution based on object class. With CoreData it would have been possible, but I do not see how to achieve that with SwiftData and DocumentGroup integration. Any idea how to do that?
1
0
135
Aug ’25
SwiftData initializing Optional Array to Empty Array
I've been seeing something that I find odd when using two SwiftData models where if I have one model (book, in this case) that has an optional array of another model (page, in this case), the optional array starts out as set to nil, but after about 20 seconds it updates to being an empty array. I see it in Previews and after building. Is this expected behavior? Should I just assume that if there is an optional array in my model it will eventually be initialized to an empty array? Code is below. import SwiftUI import SwiftData @Model final class Book { var title: String = "New Book" @Relationship var pages: [Page]? = nil init(title: String) { self.title = title } } @Model final class Page { var content: String = "Page Content" var book: Book? = nil init() { } } struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var books: [Book] var body: some View { NavigationSplitView { List { ForEach(books) { book in NavigationLink { Text("\(book.title)") Text(book.pages?.debugDescription ?? "pages is nil") } label: { Text("\(book.title)") Spacer() Text("\(book.pages?.count.description ?? "pages is nil" )") } } } HStack { Button("Clear Data") { clearData() } Button("Add Book") { addBook() } } .navigationSplitViewColumnWidth(min: 180, ideal: 200) } detail: { Text("Select an item") } } private func clearData() { for book in books { modelContext.delete(book) } try? modelContext.save() } private func addBook() { let newBook = Book(title: "A New Book") modelContext.insert(newBook) } } @main struct BookPageApp: App { var sharedModelContainer: ModelContainer = { let schema = Schema([Book.self, Page.self]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) do { return try ModelContainer(for: schema, configurations: [modelConfiguration]) } catch { fatalError("Could not create ModelContainer: \(error)") } }() var body: some Scene { WindowGroup { ContentView() } .modelContainer(sharedModelContainer) } } #Preview { ContentView() .modelContainer(for: Book.self, inMemory: true) }
1
0
165
Aug ’25
How do you observe the count of records in a Swift Data relationship?
What is the correct way to track the number of items in a relationship using SwiftData and SwiftUI? Imagine a macOS application with a sidebar that lists Folders and Tags. An Item can belong to a Folder and have many Tags. In the sidebar, I want to show the name of the Folder or Tag along with the number of Items in it. I feel like I'm missing something obvious within SwiftData to wire this up such that my SwiftUI views correctly updated whenever the underlying modelContext is updated. // The basic schema @Model final class Item { var name = "Untitled Item" var folder: Folder? = nil var tags: [Tag] = [] } @Model final class Folder { var name = "Untitled Folder" var items: [Item] = [] } @Model final class Tag { var name = "Untitled Tag" var items: [Item] = [] } // A SwiftUI view to show a Folder. struct FolderRowView: View { let folder: Folder // Should I use an @Query here?? // @Query var items: [Item] var body: some View { HStack { Text(folder.name) Spacer() Text(folder.items.count.formatted()) } } } The above code works, once, but if I then add a new Item to that Folder, then this SwiftUI view does not update. I can make it work if I use an @Query with an #Predicate but even then I'm not quite sure how the #Predicate is supposed to be written. (And it seems excessive to have an @Query on every single row, given how many there could be.) struct FolderView: View { @Query private var items: [Item] private var folder: Folder init(folder: Folder) { self.folder = folder // I've read online that this needs to be captured outside the Predicate? let identifier = folder.persistentModelID _items = Query(filter: #Predicate { link in // Is this syntax correct? The results seem inconsistent in my app... if let folder = link.folder { return folder.persistentModelID == identifier } else { return false } }) } var body: some View { HStack { Text(folder.name) Spacer() // This mostly works. Text(links.count.formatted()) } } } As I try to integrate SwiftData and SwiftUI into a traditional macOS app with a sidebar, content view and inspector I'm finding it challenging to understand how to wire everything up. In this particular example, tracking the count, is there a "correct" way to handle this?
1
0
174
Aug ’25
SwiftData Fatal error
I'm developing an app that uses CloudKit synchronization with SwiftData and on visionOS I added an App Settings bundle. I have noticed that sometimes, when the app is open and the user changes a setting from the App Settings bundle, the following fatal error occurs: SwiftData/BackingData.swift:831: Fatal error: This model instance was destroyed by calling ModelContext.reset and is no longer usable. The setting is read within the App struct in the visionOS app target using @AppStorage and this value is in turn used to set the passthrough video dimming via the .preferredSurroundingsEffect modifier. The setting allows the user to specify the dimming level as dark, semi dark, or ultra dark. The fatal error appears to occur intermittently although the first time it was observed was after adding the settings bundle. As such, I suspect there is some connection between those code changes and this fatal error even though they do not directly relate to SwiftData.
1
0
287
Oct ’25
SwiftData and CloudKit: NSKeyedUnarchiveFromData Error
I just made a small test app that uses SwiftData with CloudKit capability. I created a simple Book model as seen below. It looks like enums and structs when used with CloudKit capability all trigger this error: 'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release I fixed the error by using genreRaw String and using a computed property to use it in the app, but it popped back up after adding the ReadingProgress struct Should I ignore the error and assume Apple still supports enums and codable structs when using SwiftData with CloudKit? import SwiftData @Model class Book { var title: String = "" var author: String = "" var genreRaw: String = Genre.fantasy.rawValue var review: String = "" var rating: Int = 3 var progress: ReadingProgress? var genre: Genre { get { Genre(rawValue: genreRaw) ?? Genre.fantasy } set { genreRaw = newValue.rawValue } } init(title: String, author: String, genre: Genre, review: String, rating: Int, progress: ReadingProgress? = nil) { self.title = title self.author = author self.genre = genre self.review = review self.rating = rating self.progress = progress } } struct ReadingProgress: Codable { var currentPage: Int var totalPages: Int var isFinished: Bool var percentComplete: Double { guard totalPages > 0 else { return 0 } return Double(currentPage) / Double(totalPages) * 100 } } enum Genre: String, Codable, CaseIterable { case fantasy case scienceFiction case mystery case romance var displayName: String { switch self { case .fantasy: return "Fantasy" case .scienceFiction: return "Science Fiction" case .mystery: return "Mystery" case .romance: return "Romance" } } }
1
1
368
Sep ’25
Interactive Widget with SwiftData Not Triggering iCloud Sync
Hello everyone, I'm developing an app for iOS 18 using SwiftData, with iCloud synchronization enabled. My app also includes an interactive widget that allows users to mark tasks as complete, similar to Apple's Reminders widget. I'm facing a specific issue with how iCloud sync is triggered when changes are made from the widget. My Setup: Xcode 16 Swift 6 / iOS 18 SwiftData with iCloud Sync enabled. An interactive widget using App Intents to modify the SwiftData model. What's working correctly: App to Widget (Same Device): If I mark a task as complete in the main app, the widget on the same device updates instantly. Widget to App (Same Device): If I mark a task as complete using the interactive widget, the main app on the same device reflects this change immediately. App to App (Across Devices): If I make a change in the app on my iPhone, it syncs correctly via iCloud and appears in the app on my iPad. The Problem: The synchronization issue occurs specifically when an action is initiated from the widget and needs to be reflected on other devices, or when a change from another device needs to be reflected in the widget. Widget Change Not Syncing to Other Devices: If I mark a task as complete in the widget on my iPhone, the change does not sync to my iPad. The task on the iPad only updates after I manually open the main app on the iPhone. Remote Change Not Syncing to Widget: Similarly, if I mark a task as complete in the app on my iPad, the widget on my iPhone does not update to show this change. The widget only refreshes with the correct state after I open the main app on the iPhone. It seems that the widget's AppIntent correctly modifies the local SwiftData store, but this action isn't triggering the necessary background process to push the changes to iCloud. The sync only seems to happen when the main app, with its active ModelContainer, is brought to the foreground. My goal is for any change made in the widget to be reflected across all of the user's devices in near real-time, without requiring them to launch the main app to initiate the sync. Is there a specific API I need to call from my AppIntent to force a SwiftData sync, or a project capability I might be missing to allow the widget extension to trigger iCloud pushes? Any help or guidance would be greatly appreciated. Thank you!
1
0
158
Sep ’25
SwiftData with CloudKit in Widgets
Good morning everyone! Today I have a question about using SwiftData with CloudKit and Widgets. I recently set up my project for SwiftData and CloudKit synchronization, but for some reason, I’m not able to give my Widget access to this data. CloudKit works perfectly fine for my main app, but the Widget only shows placeholder data(the placeholder data which were defined in the get functions as catch, this is sure). I have set the CloudKit capability for my Widget extension and tried fetching data with the get-functions in the code below. I also ensured that the data model files are members of the Widget extension target and that the Widget extension uses the same CloudKit container as the main app. I wondered if it is possible and reasonable to save a copy of my CloudKit data in an App Group container, but in that case, the information shown in the Widget are not always up-to-date, so a solution that fetches data directly from CloudKit would be better. Has anyone had experience with this case? I couldn’t find much information about this problem online. In the code below, many parts have been deleted or altered because they are not relevant to the problem, as they don’t fetch data. The variables, functions, and data models in the code may sometimes have German names, but I hope you can still understand it. Thanks for your help! struct Provider: AppIntentTimelineProvider { //[Placeholder and snapshot] func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<CleverEntry> { let entry = await loadAllVariables() return Timeline(entries: [entry], policy: .after(Date().addingTimeInterval(60 * 5))) } @MainActor private func getExam() -> [PruefungM] { //Old, local version /* guard let modelContainer = try? ModelContainer(for: PruefungM.self) else { return [] } let descriptor = FetchDescriptor<PruefungM>() let PRF = try? modelContainer.mainContext.fetch(descriptor) return PRF ?? [] */ do { let configuration = ModelConfiguration(cloudKitDatabase: .private("iCloud.my_bundle_id")) let container = try ModelContainer( for: PruefungM.self, configurations: configuration ) let descriptor = FetchDescriptor<PruefungM>() return try container.mainContext.fetch(descriptor) } catch { print("❌ Error(CloudKit): \(error)") return [] } } @MainActor private func getHAF() -> [HausaufgabeM] { do { let configuration = ModelConfiguration(cloudKitDatabase: .private("iCloud.my_bundle_id")) let container = try ModelContainer( for: HausaufgabeM.self, configurations: configuration ) let descriptor = FetchDescriptor<HausaufgabeM>() return try container.mainContext.fetch(descriptor) } catch { print("❌ Error (CloudKit): \(error)") return [] } } @MainActor private func loadAllVariables() -> CleverEntry { print("Function started") let HAF = getHAF() let PRF = getExam() //handling and returning the data } }
1
1
227
Sep ’25
Inheritance in SwiftData — Fatal error: Never access a full future backing data
I'm implementing SwiftData with inheritance in an app. I have an Entity class with a property name. This class is inherited by two other classes: Store and Person. The Entity model has a one-to-many relationship with a Transaction class. I can list all my Entity models in a List with a @Query annotation without a problem. However, then I try to access the name property of an Entity from a Transaction relationship, the app crashes with the following error: Thread 1: Fatal error: Never access a full future backing data - PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(backing: SwiftData.PersistentIdentifier.PersistentIdentifierBacking.managedObjectID(0x96530ce28d41eb63 <x-coredata://DABFF7BB-C412-474E-AD50-A1F30AC6DBE9/Person/p4>))) with Optional(F07E7E23-F8F0-4CC0-B282-270B5EDDC7F3) From my attempts to fix the issue, I noticed that: The crash seems related to the relationships with classes that has inherit from another class, since it only happens there. When I create new data, I can usually access it without any problem. The crash mostly happens after reloading the app. This error has been mentioned on the forum (for example here), but in a context not related with inheritance. You can find the full code here. For reference, my models looks like this: @Model class Transaction { @Attribute(.unique) var id: String var name: String var date: Date var amount: Double var entity: Entity? var store: Store? { entity as? Store } var person: Person? { entity as? Person } init( id: String = UUID().uuidString, name: String, amount: Double, date: Date = .now, entity: Entity? = nil, ) { self.id = id self.name = name self.amount = amount self.date = date self.entity = entity } } @Model class Entity: Identifiable { @Attribute(.preserveValueOnDeletion) var name: String var lastUsedAt: Date @Relationship(deleteRule: .cascade, inverse: \Transaction.entity) var operations: [Transaction] init( name: String, lastUsedAt: Date = .now, operations: [Transaction] = [], ) { self.name = name self.lastUsedAt = lastUsedAt self.operations = operations } } @available(iOS 26, *) @Model class Store: Entity { @Attribute(.unique) var id: String var locations: [Location] init( id: String = UUID().uuidString, name: String, lastUsedAt: Date = .now, locations: [Location] = [], operations: [Transaction] = [] ) { self.locations = locations self.id = id super.init(name: name, lastUsedAt: lastUsedAt, operations: operations) } } In order to reproduce the error: Run the app in the simulator. Click the + button to create a new transaction. Relaunch the app, then click on any transaction. The app crashes when it tries to read te name property while building the details view.
1
0
272
Sep ’25
Issue with SwiftData inheritance
Every time I insert a subclass (MYShapeLayer) into the model context, the app crashes with an error: DesignerPlayground crashed due to fatalError in BackingData.swift at line 908. Never access a full future backing data - PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(backing: SwiftData.PersistentIdentifier.PersistentIdentifierBacking.managedObjectID(0xb2dbc55f3f4c57f2 <x-coredata://B1E3206B-40DE-4185-BC65-4540B4705B40/MYShapeLayer/p1>))) with Optional(A6CA4F89-107F-4A66-BC49-DD7DAC689F77) struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var designs: [MYDesign] var layers: [MYLayer] { designs.first?.layers ?? [] } var body: some View { NavigationStack { List { ForEach(layers) { layer in Text(layer.description) } } .onAppear { let design = MYDesign(title: "My Design") modelContext.insert(design) try? modelContext.save() } .toolbar { Menu("Add", systemImage: "plus") { Button(action: addTextLayer) { Text("Add Text Layer") } Button(action: addShapeLayer) { Text("Add Shape Layer") } } } } } private func addTextLayer() { if let design = designs.first { let newLayer = MYLayer(order: layers.count, kind: .text) newLayer.design = design modelContext.insert(newLayer) try? modelContext.save() } } private func addShapeLayer() { if let design = designs.first { let newLayer = MYShapeLayer(shapeName: "Ellipse", order: layers.count) newLayer.design = design modelContext.insert(newLayer) try? modelContext.save() } } } #Preview { ContentView() .modelContainer(for: [MYDesign.self, MYLayer.self, MYShapeLayer.self], inMemory: true) } @Model final class MYDesign { var title: String = "" @Relationship(deleteRule: .cascade, inverse: \MYLayer.design) var layers: [MYLayer] = [] init(title: String = "") { self.title = title } } @available(iOS 26.0, macOS 26.0, *) @Model class MYLayer { var design: MYDesign! var order: Int = 0 var title: String = "" init(order: Int = 0, title: String = "New Layer") { self.order = order self.title = title } } @available(iOS 26.0, macOS 26.0, *) @Model class MYShapeLayer: MYLayer { var shapeName: String = "" init(shapeName: String, order: Int = 0) { self.shapeName = shapeName super.init(order: order) } }
1
0
163
Sep ’25
Share Extension Lifetime and SwiftData
I have an app that uses a Share Extension that allows the user to share videos, from Files and Photos etc., the video URL and some related data is then persisted with SwiftData and synchronized with CloudKit. This code has worked consistently for a long time although recently, with iOS 26 and recent builds of iOS 18, I have observed that the video is either not saved to SwiftData (iOS 26.0), or available locally when the app is opened on the same device where the share occurred, but not synchronized to other devices (iOS 18.7 and iOS 26.1 beta). Assuming the video is opened locally after being shared into the app, it is typically synchronized with CloudKit to other devices although it's not as reliable as it should be. Is there a reliable approach in the Share Extension to ensure that the data is saved to the local SwiftData database and then synchronized with CloudKit. I suspect it could be that the lifetime of the Share Extension has become even more constrained in recent OS updates that the process ends before it has the opportunity to save and synchronize the data. Any thoughts on how to ensure this is reliable would be greatly appreciated. The data saved is not too large as it consists only of the video URL and not the data of the video itself.
1
0
191
Oct ’25
Download container SwifData from XCODE
Hi, I'm trying to download the container with SwifData of my App from the iPhone device connect through a cable to my MAC, for debug purpose. I get an error The specified file could not be transferred. Domain: com.apple.dt.CoreDeviceError Code: 7000 User Info: { DVTErrorCreationDateKey = "2025-10-30 10:00:38 +0000"; NSURL = "file:///Users/maurizio/Desktop/DatiTRIPBOOK/mm.com.TripBook%202025-10-30%2011:00.28.199.xcappdata/AppData/Library"; } The specified file could not be transferred. Domain: com.apple.dt.CoreDeviceError Code: 7000 User Info: { NSURL = "file:///Users/maurizio/Desktop/DatiTRIPBOOK/mm.com.TripBook%202025-10-30%2011:00.28.199.xcappdata/AppData/Library"; } Performing a file system operation failed. Domain: com.apple.dt.remoteservices.error Code: 11001 Failure Reason: The file could not be opened for writing. Failed to open Library/SplashBoard/Snapshots/sceneID:mm.com.TripBook-703D890D-C844-4329-B913-288B5FFB9289/9B937793-D789-43D5-B94C-3FA27A508650 for reading, openat(2) returned POSIX error code 1 (parentParam = 5) Domain: NSPOSIXErrorDomain Code: 1 Failure Reason: Operation not permitted System Information macOS Version 26.0.1 (Build 25A362) Xcode 26.0.1 (24229) (Build 17A400) Timestamp: 2025-10-30T11:00:38+01:00
1
0
150
Oct ’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
112
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
323
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
264
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
292
Nov ’25
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
183
Nov ’25
SwiftData Background Fetching?
Hi, I am experiencing main thread freezes from fetching on Main Actor. Attempting to move the function to a background thread, but whenever I reference the TestModel in a nonisolated context or in another model actor, I get this warning: Main actor-isolated conformance of 'TestModel' to 'PersistentModel' cannot be used in actor-isolated context; this is an error in the Swift 6 language mode Is there a way to do this correctly? Recreation, warning on line 13: class TestModel { var property: Bool = true init() {} } struct SendableTestModel: Sendable { let property: Bool } @ModelActor actor BackgroundActor { func fetch() throws -> [SendableTestModel] { try modelContext.fetch(FetchDescriptor<TestModel>()).map { SendableTestModel(property: $0.property) } } }
Replies
1
Boosts
0
Views
145
Activity
Jul ’25
Complex view structures are frustratingly too much work
The Java Swing and AWT MVC model made it easy to develop complex UIs with data interactions that were not described readily in a nested layer that SwiftUI demands. The implicit update model of SwiftUI greatly complicates development of applications that often requires nested components to have to know too much about other components and other structures than their own, because button events and other user interactions cannot readily alter state across layers. A button push on one component then has to be knowledgable about state in other components which have to have that state represented as @State or @Binding etc. and this causes all kinds of wiring to be spread all over the place rather than have a more centralized "state management function" that would be able to look at the world and synchronize the UIs state across changes. The fact that the compiler get's lost in the weeds when types and signatures don't match in deeper component structures doesn't help because it makes it doubly hard to do refactoring to raise and lower state management within the structure readily, because the compiler just cannot simply tell you that a function or constructor signature is no longer correct.
Replies
1
Boosts
0
Views
207
Activity
Jul ’25
Extending @Model with custom macros
I am trying to extend my PersistedModels like so: @Versioned(3) @Model class MyType { var name: String init() { name = "hello" } } but it seems that SwiftData's@Model macro is unable to read the properties added by my @Versioned macro. I have tried changing the order and it ignores them regardless. version is not added to schemaMetadata and version needs to be persisted. I was planning on using this approach to add multiple capabilities to my model types. Is this possible to do with macros? VersionedMacro /// A macro that automatically implements VersionedModel protocol public struct VersionedMacro: MemberMacro, ExtensionMacro { // Member macro to add the stored property directly to the type public static func expansion( of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] { guard let argumentList = node.arguments?.as(LabeledExprListSyntax.self), let firstArgument = argumentList.first?.expression else { throw MacroExpansionErrorMessage("@Versioned requires a version number, e.g. @Versioned(3)") } let versionValue = firstArgument.description.trimmingCharacters(in: .whitespaces) // Add the stored property with the version value return [ "public private(set) var version: Int = \(raw: versionValue)" ] } // Extension macro to add static property public static func expansion( of node: SwiftSyntax.AttributeSyntax, attachedTo declaration: some SwiftSyntax.DeclGroupSyntax, providingExtensionsOf type: some SwiftSyntax.TypeSyntaxProtocol, conformingTo protocols: [SwiftSyntax.TypeSyntax], in context: some SwiftSyntaxMacros.MacroExpansionContext ) throws -> [SwiftSyntax.ExtensionDeclSyntax] { guard let argumentList = node.arguments?.as(LabeledExprListSyntax.self), let firstArgument = argumentList.first?.expression else { throw MacroExpansionErrorMessage("@Versioned requires a version number, e.g. @Versioned(3)") } let versionValue = firstArgument.description.trimmingCharacters(in: .whitespaces) // We need to explicitly add the conformance in the extension let ext = try ExtensionDeclSyntax("extension \(type): VersionedModel {}") .with(\.memberBlock.members, MemberBlockItemListSyntax { MemberBlockItemSyntax(decl: DeclSyntax( "public static var version: Int { \(raw: versionValue) }" )) }) return [ext] } } VersionedModel public protocol VersionedModel: PersistentModel { /// The version of this particular instance var version: Int { get } /// The type's current version static var version: Int { get } } Macro Expansion:
Replies
1
Boosts
0
Views
421
Activity
Aug ’25
Mixing in-memory and persistent SwiftData containers in a Document-based App?
Hello, I'm trying to work on an iPadOS and macOS app that will rely on the document-based system to create some kind of orientation task to follow. Let say task1.myfile will be a check point regulation from NYC to SF and task2.myfile will be a visit as many key location as you can in SF. The file represent the specific landmark location and rules of the game. And once open, I will be able to read KML/GPS file to evaluate their score based with the current task. But opened GPS files does not have to be stored in the task file itself, it stay alongside. I wanted to use that scenario to experiment with SwiftData (I'm a long time CoreData user, I even wrote my own WebDAV based persistent store back in the day), and so, mix both on file and in memory persistent store, with distribution based on object class. With CoreData it would have been possible, but I do not see how to achieve that with SwiftData and DocumentGroup integration. Any idea how to do that?
Replies
1
Boosts
0
Views
135
Activity
Aug ’25
SwiftData initializing Optional Array to Empty Array
I've been seeing something that I find odd when using two SwiftData models where if I have one model (book, in this case) that has an optional array of another model (page, in this case), the optional array starts out as set to nil, but after about 20 seconds it updates to being an empty array. I see it in Previews and after building. Is this expected behavior? Should I just assume that if there is an optional array in my model it will eventually be initialized to an empty array? Code is below. import SwiftUI import SwiftData @Model final class Book { var title: String = "New Book" @Relationship var pages: [Page]? = nil init(title: String) { self.title = title } } @Model final class Page { var content: String = "Page Content" var book: Book? = nil init() { } } struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var books: [Book] var body: some View { NavigationSplitView { List { ForEach(books) { book in NavigationLink { Text("\(book.title)") Text(book.pages?.debugDescription ?? "pages is nil") } label: { Text("\(book.title)") Spacer() Text("\(book.pages?.count.description ?? "pages is nil" )") } } } HStack { Button("Clear Data") { clearData() } Button("Add Book") { addBook() } } .navigationSplitViewColumnWidth(min: 180, ideal: 200) } detail: { Text("Select an item") } } private func clearData() { for book in books { modelContext.delete(book) } try? modelContext.save() } private func addBook() { let newBook = Book(title: "A New Book") modelContext.insert(newBook) } } @main struct BookPageApp: App { var sharedModelContainer: ModelContainer = { let schema = Schema([Book.self, Page.self]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) do { return try ModelContainer(for: schema, configurations: [modelConfiguration]) } catch { fatalError("Could not create ModelContainer: \(error)") } }() var body: some Scene { WindowGroup { ContentView() } .modelContainer(sharedModelContainer) } } #Preview { ContentView() .modelContainer(for: Book.self, inMemory: true) }
Replies
1
Boosts
0
Views
165
Activity
Aug ’25
How do you observe the count of records in a Swift Data relationship?
What is the correct way to track the number of items in a relationship using SwiftData and SwiftUI? Imagine a macOS application with a sidebar that lists Folders and Tags. An Item can belong to a Folder and have many Tags. In the sidebar, I want to show the name of the Folder or Tag along with the number of Items in it. I feel like I'm missing something obvious within SwiftData to wire this up such that my SwiftUI views correctly updated whenever the underlying modelContext is updated. // The basic schema @Model final class Item { var name = "Untitled Item" var folder: Folder? = nil var tags: [Tag] = [] } @Model final class Folder { var name = "Untitled Folder" var items: [Item] = [] } @Model final class Tag { var name = "Untitled Tag" var items: [Item] = [] } // A SwiftUI view to show a Folder. struct FolderRowView: View { let folder: Folder // Should I use an @Query here?? // @Query var items: [Item] var body: some View { HStack { Text(folder.name) Spacer() Text(folder.items.count.formatted()) } } } The above code works, once, but if I then add a new Item to that Folder, then this SwiftUI view does not update. I can make it work if I use an @Query with an #Predicate but even then I'm not quite sure how the #Predicate is supposed to be written. (And it seems excessive to have an @Query on every single row, given how many there could be.) struct FolderView: View { @Query private var items: [Item] private var folder: Folder init(folder: Folder) { self.folder = folder // I've read online that this needs to be captured outside the Predicate? let identifier = folder.persistentModelID _items = Query(filter: #Predicate { link in // Is this syntax correct? The results seem inconsistent in my app... if let folder = link.folder { return folder.persistentModelID == identifier } else { return false } }) } var body: some View { HStack { Text(folder.name) Spacer() // This mostly works. Text(links.count.formatted()) } } } As I try to integrate SwiftData and SwiftUI into a traditional macOS app with a sidebar, content view and inspector I'm finding it challenging to understand how to wire everything up. In this particular example, tracking the count, is there a "correct" way to handle this?
Replies
1
Boosts
0
Views
174
Activity
Aug ’25
SwiftData CloudKit hangs on Active scene Phase
If Cloudkit is enabled, SwiftData @Query operation hangs when the View scenePhase becomes active. Seems like the more @Query calls you have, the more it hangs. This has been first documented some time ago, but in typical Apple style, it has not been addressed or even commented on. https://developer.apple.com/forums/thread/761434
Replies
1
Boosts
0
Views
214
Activity
Aug ’25
SwiftData Fatal error
I'm developing an app that uses CloudKit synchronization with SwiftData and on visionOS I added an App Settings bundle. I have noticed that sometimes, when the app is open and the user changes a setting from the App Settings bundle, the following fatal error occurs: SwiftData/BackingData.swift:831: Fatal error: This model instance was destroyed by calling ModelContext.reset and is no longer usable. The setting is read within the App struct in the visionOS app target using @AppStorage and this value is in turn used to set the passthrough video dimming via the .preferredSurroundingsEffect modifier. The setting allows the user to specify the dimming level as dark, semi dark, or ultra dark. The fatal error appears to occur intermittently although the first time it was observed was after adding the settings bundle. As such, I suspect there is some connection between those code changes and this fatal error even though they do not directly relate to SwiftData.
Replies
1
Boosts
0
Views
287
Activity
Oct ’25
SwiftData and CloudKit: NSKeyedUnarchiveFromData Error
I just made a small test app that uses SwiftData with CloudKit capability. I created a simple Book model as seen below. It looks like enums and structs when used with CloudKit capability all trigger this error: 'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release I fixed the error by using genreRaw String and using a computed property to use it in the app, but it popped back up after adding the ReadingProgress struct Should I ignore the error and assume Apple still supports enums and codable structs when using SwiftData with CloudKit? import SwiftData @Model class Book { var title: String = "" var author: String = "" var genreRaw: String = Genre.fantasy.rawValue var review: String = "" var rating: Int = 3 var progress: ReadingProgress? var genre: Genre { get { Genre(rawValue: genreRaw) ?? Genre.fantasy } set { genreRaw = newValue.rawValue } } init(title: String, author: String, genre: Genre, review: String, rating: Int, progress: ReadingProgress? = nil) { self.title = title self.author = author self.genre = genre self.review = review self.rating = rating self.progress = progress } } struct ReadingProgress: Codable { var currentPage: Int var totalPages: Int var isFinished: Bool var percentComplete: Double { guard totalPages > 0 else { return 0 } return Double(currentPage) / Double(totalPages) * 100 } } enum Genre: String, Codable, CaseIterable { case fantasy case scienceFiction case mystery case romance var displayName: String { switch self { case .fantasy: return "Fantasy" case .scienceFiction: return "Science Fiction" case .mystery: return "Mystery" case .romance: return "Romance" } } }
Replies
1
Boosts
1
Views
368
Activity
Sep ’25
Interactive Widget with SwiftData Not Triggering iCloud Sync
Hello everyone, I'm developing an app for iOS 18 using SwiftData, with iCloud synchronization enabled. My app also includes an interactive widget that allows users to mark tasks as complete, similar to Apple's Reminders widget. I'm facing a specific issue with how iCloud sync is triggered when changes are made from the widget. My Setup: Xcode 16 Swift 6 / iOS 18 SwiftData with iCloud Sync enabled. An interactive widget using App Intents to modify the SwiftData model. What's working correctly: App to Widget (Same Device): If I mark a task as complete in the main app, the widget on the same device updates instantly. Widget to App (Same Device): If I mark a task as complete using the interactive widget, the main app on the same device reflects this change immediately. App to App (Across Devices): If I make a change in the app on my iPhone, it syncs correctly via iCloud and appears in the app on my iPad. The Problem: The synchronization issue occurs specifically when an action is initiated from the widget and needs to be reflected on other devices, or when a change from another device needs to be reflected in the widget. Widget Change Not Syncing to Other Devices: If I mark a task as complete in the widget on my iPhone, the change does not sync to my iPad. The task on the iPad only updates after I manually open the main app on the iPhone. Remote Change Not Syncing to Widget: Similarly, if I mark a task as complete in the app on my iPad, the widget on my iPhone does not update to show this change. The widget only refreshes with the correct state after I open the main app on the iPhone. It seems that the widget's AppIntent correctly modifies the local SwiftData store, but this action isn't triggering the necessary background process to push the changes to iCloud. The sync only seems to happen when the main app, with its active ModelContainer, is brought to the foreground. My goal is for any change made in the widget to be reflected across all of the user's devices in near real-time, without requiring them to launch the main app to initiate the sync. Is there a specific API I need to call from my AppIntent to force a SwiftData sync, or a project capability I might be missing to allow the widget extension to trigger iCloud pushes? Any help or guidance would be greatly appreciated. Thank you!
Replies
1
Boosts
0
Views
158
Activity
Sep ’25
SwiftData with CloudKit in Widgets
Good morning everyone! Today I have a question about using SwiftData with CloudKit and Widgets. I recently set up my project for SwiftData and CloudKit synchronization, but for some reason, I’m not able to give my Widget access to this data. CloudKit works perfectly fine for my main app, but the Widget only shows placeholder data(the placeholder data which were defined in the get functions as catch, this is sure). I have set the CloudKit capability for my Widget extension and tried fetching data with the get-functions in the code below. I also ensured that the data model files are members of the Widget extension target and that the Widget extension uses the same CloudKit container as the main app. I wondered if it is possible and reasonable to save a copy of my CloudKit data in an App Group container, but in that case, the information shown in the Widget are not always up-to-date, so a solution that fetches data directly from CloudKit would be better. Has anyone had experience with this case? I couldn’t find much information about this problem online. In the code below, many parts have been deleted or altered because they are not relevant to the problem, as they don’t fetch data. The variables, functions, and data models in the code may sometimes have German names, but I hope you can still understand it. Thanks for your help! struct Provider: AppIntentTimelineProvider { //[Placeholder and snapshot] func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<CleverEntry> { let entry = await loadAllVariables() return Timeline(entries: [entry], policy: .after(Date().addingTimeInterval(60 * 5))) } @MainActor private func getExam() -> [PruefungM] { //Old, local version /* guard let modelContainer = try? ModelContainer(for: PruefungM.self) else { return [] } let descriptor = FetchDescriptor<PruefungM>() let PRF = try? modelContainer.mainContext.fetch(descriptor) return PRF ?? [] */ do { let configuration = ModelConfiguration(cloudKitDatabase: .private("iCloud.my_bundle_id")) let container = try ModelContainer( for: PruefungM.self, configurations: configuration ) let descriptor = FetchDescriptor<PruefungM>() return try container.mainContext.fetch(descriptor) } catch { print("❌ Error(CloudKit): \(error)") return [] } } @MainActor private func getHAF() -> [HausaufgabeM] { do { let configuration = ModelConfiguration(cloudKitDatabase: .private("iCloud.my_bundle_id")) let container = try ModelContainer( for: HausaufgabeM.self, configurations: configuration ) let descriptor = FetchDescriptor<HausaufgabeM>() return try container.mainContext.fetch(descriptor) } catch { print("❌ Error (CloudKit): \(error)") return [] } } @MainActor private func loadAllVariables() -> CleverEntry { print("Function started") let HAF = getHAF() let PRF = getExam() //handling and returning the data } }
Replies
1
Boosts
1
Views
227
Activity
Sep ’25
Inheritance in SwiftData — Fatal error: Never access a full future backing data
I'm implementing SwiftData with inheritance in an app. I have an Entity class with a property name. This class is inherited by two other classes: Store and Person. The Entity model has a one-to-many relationship with a Transaction class. I can list all my Entity models in a List with a @Query annotation without a problem. However, then I try to access the name property of an Entity from a Transaction relationship, the app crashes with the following error: Thread 1: Fatal error: Never access a full future backing data - PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(backing: SwiftData.PersistentIdentifier.PersistentIdentifierBacking.managedObjectID(0x96530ce28d41eb63 <x-coredata://DABFF7BB-C412-474E-AD50-A1F30AC6DBE9/Person/p4>))) with Optional(F07E7E23-F8F0-4CC0-B282-270B5EDDC7F3) From my attempts to fix the issue, I noticed that: The crash seems related to the relationships with classes that has inherit from another class, since it only happens there. When I create new data, I can usually access it without any problem. The crash mostly happens after reloading the app. This error has been mentioned on the forum (for example here), but in a context not related with inheritance. You can find the full code here. For reference, my models looks like this: @Model class Transaction { @Attribute(.unique) var id: String var name: String var date: Date var amount: Double var entity: Entity? var store: Store? { entity as? Store } var person: Person? { entity as? Person } init( id: String = UUID().uuidString, name: String, amount: Double, date: Date = .now, entity: Entity? = nil, ) { self.id = id self.name = name self.amount = amount self.date = date self.entity = entity } } @Model class Entity: Identifiable { @Attribute(.preserveValueOnDeletion) var name: String var lastUsedAt: Date @Relationship(deleteRule: .cascade, inverse: \Transaction.entity) var operations: [Transaction] init( name: String, lastUsedAt: Date = .now, operations: [Transaction] = [], ) { self.name = name self.lastUsedAt = lastUsedAt self.operations = operations } } @available(iOS 26, *) @Model class Store: Entity { @Attribute(.unique) var id: String var locations: [Location] init( id: String = UUID().uuidString, name: String, lastUsedAt: Date = .now, locations: [Location] = [], operations: [Transaction] = [] ) { self.locations = locations self.id = id super.init(name: name, lastUsedAt: lastUsedAt, operations: operations) } } In order to reproduce the error: Run the app in the simulator. Click the + button to create a new transaction. Relaunch the app, then click on any transaction. The app crashes when it tries to read te name property while building the details view.
Replies
1
Boosts
0
Views
272
Activity
Sep ’25
Issue with SwiftData inheritance
Every time I insert a subclass (MYShapeLayer) into the model context, the app crashes with an error: DesignerPlayground crashed due to fatalError in BackingData.swift at line 908. Never access a full future backing data - PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(backing: SwiftData.PersistentIdentifier.PersistentIdentifierBacking.managedObjectID(0xb2dbc55f3f4c57f2 <x-coredata://B1E3206B-40DE-4185-BC65-4540B4705B40/MYShapeLayer/p1>))) with Optional(A6CA4F89-107F-4A66-BC49-DD7DAC689F77) struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var designs: [MYDesign] var layers: [MYLayer] { designs.first?.layers ?? [] } var body: some View { NavigationStack { List { ForEach(layers) { layer in Text(layer.description) } } .onAppear { let design = MYDesign(title: "My Design") modelContext.insert(design) try? modelContext.save() } .toolbar { Menu("Add", systemImage: "plus") { Button(action: addTextLayer) { Text("Add Text Layer") } Button(action: addShapeLayer) { Text("Add Shape Layer") } } } } } private func addTextLayer() { if let design = designs.first { let newLayer = MYLayer(order: layers.count, kind: .text) newLayer.design = design modelContext.insert(newLayer) try? modelContext.save() } } private func addShapeLayer() { if let design = designs.first { let newLayer = MYShapeLayer(shapeName: "Ellipse", order: layers.count) newLayer.design = design modelContext.insert(newLayer) try? modelContext.save() } } } #Preview { ContentView() .modelContainer(for: [MYDesign.self, MYLayer.self, MYShapeLayer.self], inMemory: true) } @Model final class MYDesign { var title: String = "" @Relationship(deleteRule: .cascade, inverse: \MYLayer.design) var layers: [MYLayer] = [] init(title: String = "") { self.title = title } } @available(iOS 26.0, macOS 26.0, *) @Model class MYLayer { var design: MYDesign! var order: Int = 0 var title: String = "" init(order: Int = 0, title: String = "New Layer") { self.order = order self.title = title } } @available(iOS 26.0, macOS 26.0, *) @Model class MYShapeLayer: MYLayer { var shapeName: String = "" init(shapeName: String, order: Int = 0) { self.shapeName = shapeName super.init(order: order) } }
Replies
1
Boosts
0
Views
163
Activity
Sep ’25
Share Extension Lifetime and SwiftData
I have an app that uses a Share Extension that allows the user to share videos, from Files and Photos etc., the video URL and some related data is then persisted with SwiftData and synchronized with CloudKit. This code has worked consistently for a long time although recently, with iOS 26 and recent builds of iOS 18, I have observed that the video is either not saved to SwiftData (iOS 26.0), or available locally when the app is opened on the same device where the share occurred, but not synchronized to other devices (iOS 18.7 and iOS 26.1 beta). Assuming the video is opened locally after being shared into the app, it is typically synchronized with CloudKit to other devices although it's not as reliable as it should be. Is there a reliable approach in the Share Extension to ensure that the data is saved to the local SwiftData database and then synchronized with CloudKit. I suspect it could be that the lifetime of the Share Extension has become even more constrained in recent OS updates that the process ends before it has the opportunity to save and synchronize the data. Any thoughts on how to ensure this is reliable would be greatly appreciated. The data saved is not too large as it consists only of the video URL and not the data of the video itself.
Replies
1
Boosts
0
Views
191
Activity
Oct ’25
Download container SwifData from XCODE
Hi, I'm trying to download the container with SwifData of my App from the iPhone device connect through a cable to my MAC, for debug purpose. I get an error The specified file could not be transferred. Domain: com.apple.dt.CoreDeviceError Code: 7000 User Info: { DVTErrorCreationDateKey = "2025-10-30 10:00:38 +0000"; NSURL = "file:///Users/maurizio/Desktop/DatiTRIPBOOK/mm.com.TripBook%202025-10-30%2011:00.28.199.xcappdata/AppData/Library"; } The specified file could not be transferred. Domain: com.apple.dt.CoreDeviceError Code: 7000 User Info: { NSURL = "file:///Users/maurizio/Desktop/DatiTRIPBOOK/mm.com.TripBook%202025-10-30%2011:00.28.199.xcappdata/AppData/Library"; } Performing a file system operation failed. Domain: com.apple.dt.remoteservices.error Code: 11001 Failure Reason: The file could not be opened for writing. Failed to open Library/SplashBoard/Snapshots/sceneID:mm.com.TripBook-703D890D-C844-4329-B913-288B5FFB9289/9B937793-D789-43D5-B94C-3FA27A508650 for reading, openat(2) returned POSIX error code 1 (parentParam = 5) Domain: NSPOSIXErrorDomain Code: 1 Failure Reason: Operation not permitted System Information macOS Version 26.0.1 (Build 25A362) Xcode 26.0.1 (24229) (Build 17A400) Timestamp: 2025-10-30T11:00:38+01:00
Replies
1
Boosts
0
Views
150
Activity
Oct ’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!
Replies
1
Boosts
0
Views
112
Activity
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
Replies
1
Boosts
0
Views
323
Activity
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?
Replies
1
Boosts
0
Views
264
Activity
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?
Replies
1
Boosts
0
Views
292
Activity
Nov ’25
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.
Replies
1
Boosts
0
Views
183
Activity
Nov ’25