Magnuti
Magnuti

Reputation: 165

SwiftData handle deleted models across different context

In SwiftData lets say we have a long running background Task. For example on that calculates statistics on all items. Then the user deletes an item (a @Model instance). How can the Task handle the deleted model?

struct SomeView: View {
    @Environment(\.modelContext) private var context

    var body: some View {
        // ...
        Button("Delete item",
            action {
                context.delete(item)
                try! context.save()
            }
        )
    }
}
func calculateStatistics() {
    let actor = DataActor(modelContainer: ModelContainer)
    Task.detached {
        actor.calculateStatistics()
    }
}

...

actor DataActor {
    let modelContainer: ModelContainer
    
    init(modelContainer: ModelContainer) {
        self.modelContainer = modelContainer
    }

    func calculateStatistics() {
        let context = ModelContext(modelContainer)
        let items = try! context.fetch(FetchDescriptor<ItemModel>())

        items.calculateSums()
        items.calculateStuff()
        // ...
        // <Here the user deletes an item and we manually save or autosave happens>
        // ...
        items.calculateAverage()
    }
}

I keep getting this error on the task

SwiftData/BackingData.swift:866: Fatal error: This model instance was invalidated because its backing data could no longer be found the store. PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(url: x-coredata://22627349-2903-424B-80B4-31133FAB3C8A/ItemModel/p2), implementation: SwiftData.PersistentIdentifierImplementation)

I think the issue here is that the underlying model is deleted from storage. But how can I avoid this? Do I need to wrap everything in the same actor to prevent concurrency?

Upvotes: 0

Views: 38

Answers (0)

Related Questions