Create Complicated Nscompoundpredicate in Swift 3

Create complicated NSCompoundPredicate in swift 3

NSCompoundPredicate inherits from NSPredicate, therefore you
can pass the compound predicates created in the first steps
as subpredicate to another compound predicate:

let compound1 = NSCompoundPredicate(type: .and, subpredicates: [p1, p2, p3])
let compound2 = NSCompoundPredicate(type: .and, subpredicates: [p4, p5])
let compound3 = NSCompoundPredicate(type: .or, subpredicates: [compound1, compound2])

fetchRequest.predicate = compound3

How to create NSCompoundPredicate with empty predicate

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.

NSCompoundPredicate is giving unexpected results

Are you storing these attributes as strings rather than integers?
It could be that you're doing a comparison on the string values rather than their true numerical value, which would produce these kinds of unexpected results.

Multiple NSPredicates for NSFetchRequest in Swift?

You can use "NSCompoundPredicate". For example:

let converstationKeyPredicate = NSPredicate(format: "conversationKey = %@", conversationKey)
let messageKeyPredicate = NSPredicate(format: "messageKey = %@", messageKey)
let andPredicate = NSCompoundPredicate(type: NSCompoundPredicateType.AndPredicateType, subpredicates: [converstationKeyPredicate, messageKeyPredicate])
request.predicate = andPredicate

You can change into "AndPredicateType" or "OrPredicateType"

Building an NSCompoundPredicate from array values in Swift

The error tells you what the problem is. The format you are providing is not a valid format. Specifically, there is no "not like" comparison. You have to do the "not" outside:

NSPredicate(format: "not (boardID like %@)", board)

As @MartinR mentioned below, you can have NSPredicate automatically escape special characters so they don't interfere with the predicate by having it insert the variable instead of using string interpolation.

Swift Predicate AND and OR in one

You need two NSCompoundPredicate.

let predicate1 = NSPredicate(format: "id contains[cd] %@", searchedText)
let predicate2 = NSPredicate(format: "name contains[cd] %@", searchedText)
let predicate3 = NSPredicate(format: "threadManu = %@", manu)

let predicateOr = NSCompoundPredicate(type: .or, subpredicates: [predicate1, predicate2])
let predicate = NSCompoundPredicate(type: .and, subpredicates: [predicateOr, predicate3])

Swift - Combining Predicates

You'll need NSCompoundPredicate:

let predicate1 = NSPredicate(format: "self.label = 'foo'", argumentArray: [])
let predicate2 = NSPredicate(format: "self.label = 'bar'", argumentArray: [])
let compound = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1, predicate2])


Related Topics



Leave a reply



Submit