Search code examples
iosswiftswiftuiswiftdataswift-data-modelcontext

How to make SwiftData @Query updating from changes made on a background context?


I have a SwiftData @Query in a LazyVStack, works nicely, updates on every model change, even if I make changes in relations only.

But I also have a long running task (~3 sec), so I created a @ModelActor for that and doing the work on a detached task.

But the view does not update. 😭

If I start scolling, the newly scrolled-in items are already updated (they are probably queried fresh), but the existing items in view are not updated (not even if I scroll out and back). Only works after I restart the app.

What do you do to update a SwiftData @Query after changes on a @ModelActor background context?

I tried saving the context when task is finished, manually update the view (with setting a new state after save), but it still shows the previous state.


Solution

  • By providing a custom Identifiable implementation of the queried models, even the on-screen items gets updated.

    In my use-case the changes were made in relations, so I included the corresponding fields from relations into the Identifiable implementations as well. 👇

    extension MyModel: Identifiable {
    
        var id: String {
            "\(persistentModelID) \(relationship?.map { "\($0.persistentModelID)" }.joined() ?? "")"
        }
    }