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
What's the Rationale of Swift's Size Methods Taking 'Int'S
Sharing File Data Between Applications in Swift/Ios
Cannot Convert Value of Type 'Binding<String>' to Expected Argument Type 'Binding<String>'
Swiftui Pass Two Child Views to View
Swift 5, How to Execute Code After Fetching All Childadded from Firebase
Saving Highscores with Nsuserdefaults
Searchbar Problem While Trying to Search Firestore and Reload the Tableview
Delegate Must Respond to Locationmanager:Didupdatelocations Swift Eroor
Swift Throws Python Errors from Terminal
Codable/Decodable Should Decode Array with Strings
Ios-Charts Set Maximum Visible X Axis Values
Swift. Is the (Absolutely) Sole Specific Advantage of Unowned Over Weak, Performance
Cannot Use Tabview on Swiftui, Watchos
Swiftui: Localizedstringkey with Indices
How to Calculate the Energy Per Bin in a Dft
Integrating Congnito User Pools with Amazon Cognito Identity
How to Make Uicollectionview Reload Once It Receives Data from Firebase
Swift Error: 'Sequence' Requires the Types 'T' and 'Arrayslice<T>' Be Equivalent