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
1
0
16