Back to Swift Reference
🗄️ SwiftDataIntermediateiOS 17+

@Query, Sorting & #Predicate

Fetch models directly into a SwiftUI view — filtered, sorted and automatically kept up to date.

@Query observes the model context and re-renders the view whenever matching data changes.

Use #Predicate for type-checked filters. For dynamic filters, build the query in the view initializer.

swiftdata-query.swift
1struct HabitList: View {
2    @Environment(\.modelContext) private var context
3    @Query(sort: \Habit.createdAt, order: .reverse) private var habits: [Habit]
4
5    var body: some View {
6        List {
7            ForEach(habits) { habit in
8                Text(habit.name)
9            }
10            .onDelete { offsets in
11                offsets.map { habits[$0] }.forEach(context.delete)
12            }
13        }
14        .toolbar {
15            Button("Add") { context.insert(Habit(name: "Read 10 pages")) }
16        }
17    }
18}
19
20struct SearchResults: View {
21    @Query private var results: [Habit]
22
23    init(search: String) {
24        _results = Query(filter: #Predicate<Habit> { habit in
25            search.isEmpty || habit.name.localizedStandardContains(search)
26        }, sort: \Habit.name)
27    }
28
29    var body: some View { List(results) { Text($0.name) } }
30}

Common pitfalls

  • Not every Swift expression is supported inside #Predicate — keep it to simple comparisons and string matching.
  • SwiftData autosaves; call try context.save() explicitly when you need a guaranteed write point.

Still unclear? Ask BeeAI about @Query, Sorting & #Predicate.

Get a tailored explanation, or paste your own code for a Swift 6 review. Free members get daily questions — Pro is unlimited.

Ask BeeAI

Become a Founding Pro member: unlimited BeeAI, upcoming Swift paths and every new reference entry first.

See Pro Plans