Logo for tanaschita.com

Get started with NSPredicate to filter NSFetchRequest in Core Data

Get a quick overview on how to use predicates to filter fetch request results.

20 Mar 2023 · 3 min read

As mentioned in this guide on the main aspects of Core Data, predicates can be used to filter fetch request results.

Let's jump in and look at some examples to understand how predicates work.

Sponsorship logo
Capture HTTP(s) traffic with Proxyman
Proxyman - Your ultimate man-in-the-middle proxy to effortlessly capture, inspect, and manipulate HTTP(s) traffic on macOS, Windows, iOS, and Android devices.
Get started for free

Creating predicates

Predicates are represented by the NSPredicate type.

They represent logical conditions, which we can use to filter a collection of objects. When working with Core Data, we can filter fetch request results by setting a predicate as follows:

let usersFetchRequest = NSFetchRequest<User>(entityName: "User")
usersFetchRequest.predicate = NSPredicate(format: "isVerified == YES")

Or when using SwiftUI:

@FetchRequest(predicate: NSPredicate(format: "isVerified == YES"))
private var users: FetchedResults<User>

As we can see above, we initialize a predicate with a string format. The example will fetch all users that are verified.

The predicate used in the example can also be written by using variable substitution as follows:

NSPredicate(format: "isVerified == %@", NSNumber(value: true))

%@ is a format specifier and will be substituted with NSNumber(value: true).

Instead of referencing properties with raw strings, we could use key paths to add more safety to our code by using the %K format specifier:

NSPredicate(format: "%K == %@", #keyPath(User.isVerified), NSNumber(value: true))

Format specifiers

As we already saw above, format specifiers allow us to use variable substitution. Examples of format specifiers are:

  • %@ for objects
  • @K for key paths
  • @d for integers
  • @f for floating numbers

Checkout Apple's official documentation to discover more format specifiers.

Comparison predicate operators

In the example above, we used == as comparison operator for an exact match.

We could also use compare operators like !=, >=, >, <= < etc. which are self-explanatory. An example to filter all users who reached the age of 18 could look this way:

NSPredicate(format: "age >= 18")

Two more interesing compare operators are IN and BETWEEN:

IN can be used to provide an array of values to match. For example, to filter all users of certain ages:

NSPredicate(format:"age IN %@", agesArray)

BETWEEN can be used to provide a range to match:

NSPredicate(format:"age BETWEEN {12, 17}")

When working with strings, we can also use comparison operators BEGINSWITH, CONTAINS or ENDSWITH. For example, to match all users which last names begin with a t:

NSPredicate(format:"lastName BEGINSWITH 't'")

Compound predicate operators

To combine multipe predicates, we can use standard logical operators:

For example:

NSPredicate(format:"age >= 18 AND isVerified == YES")

Conclusion

While NSPredicate is a powerful filter mechanism, it does come with downsides when used in Swift. Since queries are written as raw strings, we don't get any compile-time safety, mistakes are only noticed at runtime.

In this article, we only discovered the basics of predicates. To dive deeper, check out Apple's official programming guide.

Sponsorship logo
Capture HTTP(s) traffic with Proxyman
Proxyman - Your ultimate man-in-the-middle proxy to effortlessly capture, inspect, and manipulate HTTP(s) traffic on macOS, Windows, iOS, and Android devices.
Get started for free

Newsletter

Image of a reading marmot
Subscribe

Like to support my work?

Say hi

Related tags

Articles with related topics

core data

persistence

xcode

swift

ios

iOS developer guide on the main aspects of Core Data

Understand the main concepts of the Core Data framework.

19 Sep 2022 · 5 min read

Latest articles and tips

© 2023 tanaschita.com

Privacy policy

Impressum