https://developer.apple.com/documentation/swiftdata/filtering-and-sorting-persistent-data provides instructions for using @Query
inside a View
.
But, what do I do if the query is complex or I want to share it b/w multiple Views?
Can I define it on the @Model
class itself? Somewhere else other than the View
? Or, is it best practice to specify all queries and subsequent data processing within each View
and duplicate it for any other Views
that depend on the same query?
Since each query is for a specific model class it feels only natural to define them on the model itself. Now a @Query
can't be used outside of a view so it's better to work with a Predicate
or a FetchDescriptor
.
I use the latter so that is what my examples below returns a FetchDescriptor
.
I declare my static queries as static variable and the dynamic ones as static functions
For instance
@Model
final class MyModel {
var isActive: Bool
//...
}
I prefer to move the queries to a separate extension
extension MyModel {
static var activeModels: FetchDescriptor<MyModel> {
FetchDescriptor(predicate: #Predicate<MyModel> { $0.isActive })
}
static func fetch(active: Bool) -> FetchDescriptor<MyModel> {
FetchDescriptor(predicate: #Predicate<MyModel> { $0.isActive == active })
}
}
And a solution like this can then be used in a view or when fetching outside a view in the same manner
@Query(MyModel.activeModels) private var allActive: [MyModel]
or
let active = modelContext.fetch(MyModel.activeModels)