SwiftData filtering Query with computed property – Swift

by
Maya Patel
swift-concurrency swift-data

Quick Fix: Create a static variable to store the current date and use it in the predicate instead of the computed property. Remember, computed properties cannot be used in queries as they are evaluated at runtime, but stored properties are allowed.

The Problem:

A Swift developer is trying to filter data in a SwiftUI application using the SwiftData framework. They have a model called Item with a computed property called isEnded, which determines if the item has ended based on a comparison between the end date and the current date. They are using a @Query property wrapper to fetch items that have ended, sorted by their start date. However, the developer is encountering a crash when trying to fetch the data, with an error message indicating that the isEnded property cannot be found on the Item model.

The Solutions:

Solution 1: Predicate without computed property

Computed properties cannot be directly used in a query because queries are executed on the database and only stored properties are directly accessible. To work around this, you can define a static variable to represent the current date and use it in a predicate like this:

“`
private static var now: Date { Date.now }
@Query(filter: #Predicate {
if $0.end == nil {
return false
} else {
return $0.end! < now
}
}, sort: [SortDescriptor(\Item.start)], animation: .bouncy)
“`

This way, the query will use the current date to determine whether an item is ended or not. Here, we define a static variable named now to represent the current date. Then, in the predicate, we check if the end property of an item is nil. If it is, we return false because there is no end date to compare. Otherwise, we compare the end property with the now variable to determine if the item is ended.

Q&A

Can computed properties be used to create predicate for @Query?

No, computed properties can’t be used in a query, only stored properties are allowed.

How to write the predicate without the computed property?

Use a variable that contains the value of the computed property instead of calling it directly in the predicate.

Video Explanation:

The following video, titled "Core Data Tutorial - Lesson 4: Sorting and Filtering - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

Learn how to filter and sort the data returned from your Core Data database! In this lesson, I'll teach you about predicates and sort ...