Dawy
Dawy

Reputation: 946

How to create NSCompoundPredicate with "empty" predicate

I try to combine more individual predicates into one via NSCompoundPredicate but it may happen that one or more predicates are not constructed because all objects should be retrieved from CoreData entity (so no predicate is actually needed).

if isGenreFilterOn {
    genrePredicate = NSPredicate(format: "genID == \(genreID)")
}
if searchFor != "" {    
    bookPredicate = NSPredicate(format: "bokName CONTAINS[cd] %@", searchFor)
}
let predicate = NSCompoundPredicate(type: .and, subpredicates: [genrePredicate, bookPredicate])

App fails in case the any of the predicates is not constructed. What is the best way to avoid of many if clauses, should I rather construct predicates retrieving all objects from entity or is there any clever way? Thanks.

Upvotes: 2

Views: 1101

Answers (2)

Martin R
Martin R

Reputation: 539795

Instead of creating “empty” predicates you can dynamically build an array containing only the needed predicates:

var predicates = [NSPredicate]() // Start with empty list.
if isGenreFilterOn {
    // Add genre predicate:
    predicates.append(NSPredicate(format: "genID == \(genreID)"))
}
if !searchFor.isEmpty {
    // Add book predicate:
    predicates.append(NSPredicate(format: "bokName CONTAINS[cd] %@", searchFor))
}
// ... more criteria ...

// Combine all predicates:
let predicate = NSCompoundPredicate(type: .and, subpredicates: predicates)

More optional (or non-optional) criteria can easily be added. This works correctly even if the predicates array is empty.


Remark: Be careful with string interpolation in predicate format strings.

NSPredicate(format: "genID == \(genreID)")

is fine if genreID is a number, but can crash at runtime if it is a string and contains any special characters or reserved keywords for predicates.

Upvotes: 4

Tom Harrington
Tom Harrington

Reputation: 70946

What you’re calling an empty predicate is one that always evaluates to “true”. You can do that— use NSPredicate(value: true) in place of either of your predicates when you don’t need them. With one always-true predicate, your compound evaluates the other one. If both are always true, the compound is always true, and it’s the same as having no predicate.

Upvotes: 2

Related Questions