Search results for

“SwiftData inheritance relationship”

4,981 results found

Post

Replies

Boosts

Views

Activity

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.forma
1
0
174
Aug ’25
SwiftData ModelContext.insert crashes, why?
This simple test fails in my project. Similar code in my application also crashes. How do I debug the problem? What project settings are required. I have added SwiftData as a framework to test (and application) targets? Thanks, The problem is with: modelContext.insert(item) Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) import XCTest import SwiftData @Model class FakeModel { var name: String init(name: String) { self.name = name } } @MainActor final class FakeModelTests: XCTestCase { var modelContext: ModelContext! override func setUp() { super.setUp() do { let container = try ModelContainer(for: FakeModel.self, configurations: ModelConfiguration(isStoredInMemoryOnly: true)) modelContext = container.mainContext } catch { XCTFail(Failed to create ModelContainer: (error)) modelContext = nil } } func testSaveFetchDeleteFakeItem() { guard let modelContext = modelContext else { XCTFail(ModelContext must be initialized) return } let item = FakeModel(name: Test) modelContext.inser
4
0
267
Aug ’25
SwiftData crash when switching between Window and ImmersiveSpace in visionOS
Environment visionOS 26 Xcode 26 Issue I am experiencing crash when trying to access a [String] from a @Model data, after dismissing an immersiveSpace and opening a WindowGroup. This crash only occurs when trying to access the [String] property of my Model. It works fine with other properties. Thread 1: Fatal error: This backing data was detached from a context without resolving attribute faults: PersistentIdentifier(...) Steps to Reproduce Open WindowGroup Dismiss window, open ImmersiveSpace Dismiss ImmersiveSpace, reopen WindowGroup Any guidance would be appreciated! @main struct MyApp: App { var body: some Scene { WindowGroup(id: main) { ContentView() } .modelContainer(for: [Item.self]) ImmersiveSpace(id: immersive) { ImmersiveView() } } } // In SwiftData model @Model class Item { var title: String = // Accessing this property works fine var tags: [String] = [] @storageRestrictions(accesses: _$backingData, initializes: _tags) init(initialValue) { _$backingData.setValue(forKey: . tags, to: initial
3
0
229
Aug ’25
Reply to SwiftData Fatal error: Editors must register their identifiers before invoking operations on this store
@DTS Engineer thank you for these suggestions. I've added the full crash report from Crashlytics to this post. After enabling the launch argument you suggested, I managed to reproduce the crash in the debugger once, so that's some progress. After enabling Swift 6 and complete concurrency checking, I got some build errors in the class owning the ModelActor. Wherever I accessed the ModelActor, I got this error: Sending 'self.localStorage.some' risks causing data races. As mentioned in my original post, the ModelActor conforms to a protocol because I am using another type of storage in iOS 16 which doesn't support SwiftData. This protocol didn't require that conforming types were Actors, leading me to suspect that the class owning the ModelActor didn't treat it as an actor, because it only know about the protocol. Adding the Actor requirement to the protocol, removed the build errors in the owning class. Now, I have to ship this change to confirm that it actually fixes it, since I cannot reliably reprod
Aug ’25
Reply to Should ModelActor be used to populate a view?
I decided to run this task on app launch to sync the clinical labs into the SwiftData store. This allows me to use Query macro in the views where it's needed and no need to combine lab results. Let me know if this is the right approach: import SwiftData import SwiftUI import OSLog @ModelActor actor HealthKitSyncManager { private let logger = Logger(subsystem: com.trtmanager, category: HealthKitSyncManager) func sync() async { do { // Get all Clinical labs let hkClinicalRecords = try await TRTHealthKitService.getHKClinicalRecords() guard !hkClinicalRecords.isEmpty else { return } // Get existing HealthKit IDs in one query let descriptor = FetchDescriptor( // predicate: #Predicate { $0.source == .clinicalRecord } ) let existing = try modelContext.fetch(descriptor) .compactMap { $0.fhirResourceId } let existingIDs = Set(existing) let missingRecords = hkClinicalRecords.filter { lab in guard let fhirResource = lab.fhirResource else { return false } return !existingIDs.contains(fhirResource.identi
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’25
Should ModelActor be used to populate a view?
I'm working with SwiftData and SwiftUI and it's not clear to me if it is good practice to have a @ModelActor directly populate a SwiftUI view. For example when having to combine manual lab results and clinial results from HealthKit. The Clinical lab results are an async operation: @ModelActor actor LabResultsManager { func fetchLabResultsWithHealthKit() async throws -> [LabResultDto] { let manualEntries = try modelContext.fetch(FetchDescriptor()) let clinicalLabs = (try? await HealthKitService.getLabResults()) ?? [] return (manualEntries + clinicalLabs).sorted { $0.date > $1.date }.map { return LabResultDto(from: $0) } } } struct ContentView: View { @State private var labResults: [LabResultDto] = [] var body: some View { List(labResults, id: .id) { result in VStack(alignment: .leading) { Text(result.testName) Text(result.date, style: .date) } } .task { do { let labManager = LabResultsManager() labResults = try await labManager.fetchLabResultsWithHealthKit() } catch { // Handle error } } } } EDI
4
0
260
Aug ’25
Reply to SwiftData Fatal error: Editors must register their identifiers before invoking operations on this store
Do you have a full symbolicated crash report to share? You can include crash reports directly in your post using the forums attachment feature. For any random crash related to SwiftData / Core Data, I'd suggest that you add com.apple.CoreData.ConcurrencyDebug 1 as a launch argument of the app to check if there is any violation, as discussed here. Also, I guess ConsumptionSession is Sendable? Otherwise, Xcode will give you an error if you compile with Swift 6. If you haven't used Swift 6, I'd suggest that you give it a try to see if that unveils any race condition. Best, —— Ziqiao Chen  Worldwide Developer Relations.
Aug ’25
Reply to Should ModelActor be used to populate a view?
It's unclear what LabResultDto in the code snippet is. If it is a Sendable type that wraps the data in a SwiftData model, that's fine; if it is a SwiftData model type, because a SwiftData model object is not Sendable, you won't want to pass it across actors – Otherwise, Swift 6 compiler will give you an error. For more information about this topic, see the discussion here. When using SwiftData + SwiftUI, I typically use @Query to create a result set for a view. Under the hood (of @Query), the query controller should be able to detect the changes you made from within a model actor, and trigger a SwiftUI update. Fore more information about observing SwiftData changes, see this WWDC25 video. Best, —— Ziqiao Chen  Worldwide Developer Relations.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’25
Reply to How to get PersistentIdentifier from a model created in a transaction?
Thank you @Aloisius for your following up. I'd like to confirm that you are right, and I was wrong. SwiftData does use a temporary identifier for a model that is not persisted yet. The identifier is converted to a permanent one when the model is saved. In the case of using transaction(block:), the transaction takes care the saving, and so the identifier does change when the scope goes outside the transaction block. This behavior originates in Core Data (SwiftData DefaultStore is based on Core Data). Core Data provides a way to obtain a permanent ID for a managed object (obtainPermanentIDs(for:)), while SwiftData doesn't, and so I was in an impression that persistentModelID had eliminated the difference – That is actually wrong. I've removed my previous reply to avoid confusing people. Sorry for that. Saving a model makes the model's persistentModelID permanent. Assuming that I need to set up an object graph in a transaction, I'd probably consider the following: Create the root item
Aug ’25
Reply to SwiftData initializing Optional Array to Empty Array
What you observed is the behavior that the framework currently has – If you save the model context right after adding a book, you will see that the relationship turns from nil to [] immediately, and that's because SwiftData makes the change when persisting the model. SwiftData does that because the default store (DefaultStore) is based on Core Data, and Core Data expresses an empty toMany relationship with an empty set. (Core Data had been implemented with Objective C long before Swift was introduced.) Having said that, if you have a different opinion about the behavior, feel free to file a feedback report – If you do so, please share your report ID here. Thanks. Best, —— Ziqiao Chen  Worldwide Developer Relations.
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(
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.forma
Replies
1
Boosts
0
Views
174
Activity
Aug ’25
Reply to SwiftData Inheritance Query Specialized Model
The use of the inheritance, as shown in the above code snippet, looks fine to me, and I don't really see a crash by running the code on my iOS 26 Beta 7 simulator and device. So did you try with Beta 7, the latest Beta as of today, yet? Best, —— Ziqiao Chen  Worldwide Developer Relations.
Replies
Boosts
Views
Activity
Aug ’25
SwiftData ModelContext.insert crashes, why?
This simple test fails in my project. Similar code in my application also crashes. How do I debug the problem? What project settings are required. I have added SwiftData as a framework to test (and application) targets? Thanks, The problem is with: modelContext.insert(item) Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) import XCTest import SwiftData @Model class FakeModel { var name: String init(name: String) { self.name = name } } @MainActor final class FakeModelTests: XCTestCase { var modelContext: ModelContext! override func setUp() { super.setUp() do { let container = try ModelContainer(for: FakeModel.self, configurations: ModelConfiguration(isStoredInMemoryOnly: true)) modelContext = container.mainContext } catch { XCTFail(Failed to create ModelContainer: (error)) modelContext = nil } } func testSaveFetchDeleteFakeItem() { guard let modelContext = modelContext else { XCTFail(ModelContext must be initialized) return } let item = FakeModel(name: Test) modelContext.inser
Replies
4
Boosts
0
Views
267
Activity
Aug ’25
Reply to SwiftData ModelContext.insert crashes, why?
Answering my own question. Found this blog, searching for answers https://blog.jacobstechtavern.com/p/swiftdata-outside-swiftui Thanks Jacob. The answer is simple, but maybe someone can explain. modelContext = container.mainContext works if it's modelContext = ModelContext(container) Done!
Replies
Boosts
Views
Activity
Aug ’25
Reply to SwiftData Inheritance Query Specialized Model
You haven’t provided the details about CollectionItem which seems to be the class that causes the crash but I must say that it’s a very strange design you have where the superclass both has a children property of self and is being inherited. Do you really need such a complex solution?
Replies
Boosts
Views
Activity
Aug ’25
SwiftData crash when switching between Window and ImmersiveSpace in visionOS
Environment visionOS 26 Xcode 26 Issue I am experiencing crash when trying to access a [String] from a @Model data, after dismissing an immersiveSpace and opening a WindowGroup. This crash only occurs when trying to access the [String] property of my Model. It works fine with other properties. Thread 1: Fatal error: This backing data was detached from a context without resolving attribute faults: PersistentIdentifier(...) Steps to Reproduce Open WindowGroup Dismiss window, open ImmersiveSpace Dismiss ImmersiveSpace, reopen WindowGroup Any guidance would be appreciated! @main struct MyApp: App { var body: some Scene { WindowGroup(id: main) { ContentView() } .modelContainer(for: [Item.self]) ImmersiveSpace(id: immersive) { ImmersiveView() } } } // In SwiftData model @Model class Item { var title: String = // Accessing this property works fine var tags: [String] = [] @storageRestrictions(accesses: _$backingData, initializes: _tags) init(initialValue) { _$backingData.setValue(forKey: . tags, to: initial
Replies
3
Boosts
0
Views
229
Activity
Aug ’25
Reply to SwiftData Fatal error: Editors must register their identifiers before invoking operations on this store
@DTS Engineer thank you for these suggestions. I've added the full crash report from Crashlytics to this post. After enabling the launch argument you suggested, I managed to reproduce the crash in the debugger once, so that's some progress. After enabling Swift 6 and complete concurrency checking, I got some build errors in the class owning the ModelActor. Wherever I accessed the ModelActor, I got this error: Sending 'self.localStorage.some' risks causing data races. As mentioned in my original post, the ModelActor conforms to a protocol because I am using another type of storage in iOS 16 which doesn't support SwiftData. This protocol didn't require that conforming types were Actors, leading me to suspect that the class owning the ModelActor didn't treat it as an actor, because it only know about the protocol. Adding the Actor requirement to the protocol, removed the build errors in the owning class. Now, I have to ship this change to confirm that it actually fixes it, since I cannot reliably reprod
Replies
Boosts
Views
Activity
Aug ’25
Reply to Should ModelActor be used to populate a view?
I decided to run this task on app launch to sync the clinical labs into the SwiftData store. This allows me to use Query macro in the views where it's needed and no need to combine lab results. Let me know if this is the right approach: import SwiftData import SwiftUI import OSLog @ModelActor actor HealthKitSyncManager { private let logger = Logger(subsystem: com.trtmanager, category: HealthKitSyncManager) func sync() async { do { // Get all Clinical labs let hkClinicalRecords = try await TRTHealthKitService.getHKClinicalRecords() guard !hkClinicalRecords.isEmpty else { return } // Get existing HealthKit IDs in one query let descriptor = FetchDescriptor( // predicate: #Predicate { $0.source == .clinicalRecord } ) let existing = try modelContext.fetch(descriptor) .compactMap { $0.fhirResourceId } let existingIDs = Set(existing) let missingRecords = hkClinicalRecords.filter { lab in guard let fhirResource = lab.fhirResource else { return false } return !existingIDs.contains(fhirResource.identi
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Aug ’25
Should ModelActor be used to populate a view?
I'm working with SwiftData and SwiftUI and it's not clear to me if it is good practice to have a @ModelActor directly populate a SwiftUI view. For example when having to combine manual lab results and clinial results from HealthKit. The Clinical lab results are an async operation: @ModelActor actor LabResultsManager { func fetchLabResultsWithHealthKit() async throws -> [LabResultDto] { let manualEntries = try modelContext.fetch(FetchDescriptor()) let clinicalLabs = (try? await HealthKitService.getLabResults()) ?? [] return (manualEntries + clinicalLabs).sorted { $0.date > $1.date }.map { return LabResultDto(from: $0) } } } struct ContentView: View { @State private var labResults: [LabResultDto] = [] var body: some View { List(labResults, id: .id) { result in VStack(alignment: .leading) { Text(result.testName) Text(result.date, style: .date) } } .task { do { let labManager = LabResultsManager() labResults = try await labManager.fetchLabResultsWithHealthKit() } catch { // Handle error } } } } EDI
Replies
4
Boosts
0
Views
260
Activity
Aug ’25
Reply to SwiftData Fatal error: Editors must register their identifiers before invoking operations on this store
Do you have a full symbolicated crash report to share? You can include crash reports directly in your post using the forums attachment feature. For any random crash related to SwiftData / Core Data, I'd suggest that you add com.apple.CoreData.ConcurrencyDebug 1 as a launch argument of the app to check if there is any violation, as discussed here. Also, I guess ConsumptionSession is Sendable? Otherwise, Xcode will give you an error if you compile with Swift 6. If you haven't used Swift 6, I'd suggest that you give it a try to see if that unveils any race condition. Best, —— Ziqiao Chen  Worldwide Developer Relations.
Replies
Boosts
Views
Activity
Aug ’25
Reply to Should ModelActor be used to populate a view?
It's unclear what LabResultDto in the code snippet is. If it is a Sendable type that wraps the data in a SwiftData model, that's fine; if it is a SwiftData model type, because a SwiftData model object is not Sendable, you won't want to pass it across actors – Otherwise, Swift 6 compiler will give you an error. For more information about this topic, see the discussion here. When using SwiftData + SwiftUI, I typically use @Query to create a result set for a view. Under the hood (of @Query), the query controller should be able to detect the changes you made from within a model actor, and trigger a SwiftUI update. Fore more information about observing SwiftData changes, see this WWDC25 video. Best, —— Ziqiao Chen  Worldwide Developer Relations.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Aug ’25
Reply to How to get PersistentIdentifier from a model created in a transaction?
Thank you @Aloisius for your following up. I'd like to confirm that you are right, and I was wrong. SwiftData does use a temporary identifier for a model that is not persisted yet. The identifier is converted to a permanent one when the model is saved. In the case of using transaction(block:), the transaction takes care the saving, and so the identifier does change when the scope goes outside the transaction block. This behavior originates in Core Data (SwiftData DefaultStore is based on Core Data). Core Data provides a way to obtain a permanent ID for a managed object (obtainPermanentIDs(for:)), while SwiftData doesn't, and so I was in an impression that persistentModelID had eliminated the difference – That is actually wrong. I've removed my previous reply to avoid confusing people. Sorry for that. Saving a model makes the model's persistentModelID permanent. Assuming that I need to set up an object graph in a transaction, I'd probably consider the following: Create the root item
Replies
Boosts
Views
Activity
Aug ’25
Reply to SwiftData initializing Optional Array to Empty Array
What you observed is the behavior that the framework currently has – If you save the model context right after adding a book, you will see that the relationship turns from nil to [] immediately, and that's because SwiftData makes the change when persisting the model. SwiftData does that because the default store (DefaultStore) is based on Core Data, and Core Data expresses an empty toMany relationship with an empty set. (Core Data had been implemented with Objective C long before Swift was introduced.) Having said that, if you have a different opinion about the behavior, feel free to file a feedback report – If you do so, please share your report ID here. Thanks. Best, —— Ziqiao Chen  Worldwide Developer Relations.
Replies
Boosts
Views
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(
Replies
1
Boosts
0
Views
165
Activity
Aug ’25
Reply to Should ModelActor be used to populate a view?
It's best to use @Query to fetch data when working with UI, like in this case. ModelActor is is meant to work on background operations. But SwiftData is also fundamentally broken when merging changes between background and foreground contexts. I would avoid at all costs.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Aug ’25