Delay when using ResultsObserver over @Query?

I was testing how to use ResultsObserver on a ViewModel in SwiftData.

In Xcode 27, Developer v1, I have the following view

import SwiftUI
import SwiftData

@Model
class TaskItem {
    var name: String
    var priority: Int

    init(name: String, priority: Int) {
        self.name = name
        self.priority = priority
    }
}

@Observable @MainActor
class RandomViewModel {
    let observer: ResultsObserver<TaskItem, Never>
    
    @ObservationIgnored private var token: ObservationTracking.Token?


    var tasks: FetchResultsCollection<TaskItem> {
        observer.results
    }

    init(context: ModelContext) {
        let descriptor = FetchDescriptor<TaskItem>(
            sortBy: [SortDescriptor(\.name, order: .reverse)]
        )

        observer = try! ResultsObserver(fetchDescriptor: descriptor, modelContext: context)
    }
}

struct RandomView: View {
    @State var viewModel: RandomViewModel?
    @Environment(\.modelContext) private var modelContext

    var body: some View {
        VStack {
            if let viewModel {
                List(viewModel.tasks) { foo in
                    Text(foo.name)
                }
                .toolbar {
                    ToolbarItem(placement: .primaryAction) {
                        Button("Add Task") {
                            let task = TaskItem(name: "ZZ New Task \(viewModel.observer.results.count + 1)", priority: 2)
                            print("add \(task.name)")
                            modelContext.insert(task)
                        }
                    }
                }
            } else {
                Text("Hello, World!")
            }
        }
        .task {
            if viewModel == nil {
                viewModel = RandomViewModel(context: modelContext)
            }
        }
    }
}

func testContainer() -> ModelContainer {
    let schema = Schema([
        Item.self,
        TaskItem.self,
    ])
    let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true)
    let container = try! ModelContainer(for: schema, configurations: [modelConfiguration])
    let modelContext = container.mainContext

    for i in 1...20 {
        let item = TaskItem(name: "Sample Task \(i)", priority: Int.random(in: 1...5))
        modelContext.insert(item)
    }

    return container
}

#Preview {
    NavigationStack {
        RandomView()
    }
    .modelContainer(testContainer())
}

When I run the Preview or the simulator, the UI takes a while to actually load and show the results.

If I try a version using @Query this doesn't happen

import SwiftData
import SwiftUI

struct RandomQueryView: View {
    @Environment(\.modelContext) private var modelContext
    @Query(sort: [SortDescriptor(\TaskItem.name, order: .reverse)]) private var tasks: [TaskItem]

    var body: some View {
        List(tasks) { task in
            Text(task.name)
        }
        .toolbar {
            ToolbarItem(placement: .primaryAction) {
                Button("Add Task") {
                    let task = TaskItem(name: "ZZ New Task \(tasks.count + 1)", priority: 2)
                    print("add \(task.name)")
                    modelContext.insert(task)
                }
            }
        }
    }
}

#Preview {
    NavigationStack {
        RandomQueryView()
    }
    .modelContainer(testContainer())
}

Is this a bug in SwiftData ResultsObserver? or am I using it wrong?

I add a recording of my simulator showing the difference

The point of .task is to remove the need for a class. Try wrapping ResultsObserver in AsyncStream and set the results on @.State in a for await loop.

Delay when using ResultsObserver over &#64;Query?
 
 
Q