SwiftData Crash On Models With Relationships Deletion

It seems that when you delete model objects with a relationship there seems to be a crash occurring if the collection your observing is tied to a ForEach. Below is an example of the models in SwiftData

@Model
class Category {
    
    @Attribute(.unique)
    var title: String
    
    var items: [Item]?
    
    init(title: String = "") {
        self.title = title
    }
}

The relationship is defined between the category and the item

@Model
final class Item {
    var title: String
    var timestamp: Date
    var isCritical: Bool
    var isCompleted: Bool

    @Relationship(.nullify, inverse: \Category.items)
    var category: Category?
    
    init(title: String = "",
         timestamp: Date = .now,
         isCritical: Bool = false,
         isCompleted: Bool = false) {
        self.title = title
        self.timestamp = timestamp
        self.isCritical = isCritical
        self.isCompleted = isCompleted
    }
}

So if I were to create a category individually so i can later tag it to an item i'm just following the standard proceedure of creating a category and inserting it into the context as you can see below

                Button("Add Category") {
                    let category = Category(title: title)
                    modelContext.insert(category)
                }
                .disabled(title.isEmpty)

Then later on when i create my item I associated an existing category with an item and insert that into the context so now there is a possibility to have many items associated to a single category as you can see below

    @State var item = Item()

// Item is bound to form elements
....

                Button("Create") {
                    modelContext.insert(item)
                    item.category = selectedCategory.title == "None" ? nil : selectedCategory
                    dismiss()
                }

This is where the problem occurs...

If i try to delete a category now after inserting it


    @Query private var categories: [Category]

....
                    ForEach(categories) { category in
                        Text(category.title)
                            .swipeActions(allowsFullSwipe: true) {
                                
                                Button(role: .destructive) {

                                    withAnimation {
                                       modelContext.delete(category)
                                    }
                                        
                                } label: {
                                    Label("Delete", systemImage: "trash.fill")
                                }
                                
                            }
                    }

The application crashes because the foreach is still being executed by the Query property wrapper as if the item still exists even though it has been deleted, but it's trying to access the title on an object that doesn't exist anymore.

I've also noticed that when trying to insert duplicate items using the Atrribute macros this causes a crash too.

It's almost as if the query collection just isn't being updated with the new values of a category being deleted. I've filed a feedback under FB12286699 (Crash when deleting items in relationships) in Feedback assistent hopefully this can get picked up.

If you mark the properties in Category as optional then it works fine with no crashes. But then you don't get uniqueness and you're able to insert duplicates into the context.

While I can't help with an answer here I can say I was able to finally sort out how to do a 1:Many relationship from your example. The early documentation and examples out there seem to totally avoid really explaining how this works.

I do also face the crashing in the same situation. I have a parent child relationship which have a 1:many relationship. Deleting child elements works fine, but as soon as I want to delete the parent the application is crashing for me in Xcode 15.0 Beta 2. I do hope this is still a beta issue or there is some official of way of deleting such a relationship gracefully in the future.

I am not sure if the following helps

Xcode 15 beta 2 release notes

SwiftData

Known Issues After deleting an item, SwiftUI may attempt to reference the deleted content during the animation causing a crash. (109838173)

Workaround: Explicitly save after a delete.

I've been able to resolve some of my deletion issues by nullifying the relationships prior to deleting the model object from the context.

SwiftData Crash On Models With Relationships Deletion
 
 
Q