Bassed on markjs answer, I translated it to swift 4 and placed it in a extension of NSPredicateEditorRowTemplate.
extension NSPredicateEditorRowTemplate {
convenience init( compoundTypes: [NSCompoundPredicate.LogicalType] ) {
var compoundTypesNSNumber: [NSNumber] = []
for c in compoundTypes { compoundTypesNSNumber.append( NSNumber(value: c.rawValue) ) }
self.init( compoundTypes: compoundTypesNSNumber )
}
convenience init( forKeyPath keyPath: String, withValues values: [Any] ) {
let keyPaths: [NSExpression] = [NSExpression(forKeyPath: keyPath)]
var constantValues: [NSExpression] = []
for v in values {
constantValues.append( NSExpression(forConstantValue: v) )
}
let operators: [NSComparisonPredicate.Operator] = [.equalTo, .notEqualTo]
var operatorsNSNumber: [NSNumber] = []
for o in operators { operatorsNSNumber.append( NSNumber(value: o.rawValue) ) }
self.init( leftExpressions: keyPaths,
rightExpressions: constantValues,
modifier: .direct,
operators: operatorsNSNumber,
options: (Int(NSComparisonPredicate.Options.caseInsensitive.rawValue | NSComparisonPredicate.Options.diacriticInsensitive.rawValue)) )
}
convenience init( stringCompareForKeyPaths keyPaths: [String] ) {
var leftExpressions: [NSExpression] = []
for keyPath in keyPaths {
leftExpressions.append( NSExpression(forKeyPath: keyPath) )
}
let operators: [NSComparisonPredicate.Operator] = [.contains, .equalTo, .notEqualTo, .beginsWith, .endsWith]
var operatorsNSNumber: [NSNumber] = []
for o in operators { operatorsNSNumber.append( NSNumber(value: o.rawValue) ) }
self.init( leftExpressions: leftExpressions,
rightExpressionAttributeType: .stringAttributeType,
modifier: .direct,
operators: operatorsNSNumber,
options: (Int(NSComparisonPredicate.Options.caseInsensitive.rawValue | NSComparisonPredicate.Options.diacriticInsensitive.rawValue)) )
}
convenience init( IntCompareForKeyPaths keyPaths: [String] ) {
var leftExpressions: [NSExpression] = []
for keyPath in keyPaths {
leftExpressions.append( NSExpression(forKeyPath: keyPath) )
}
let operators: [NSComparisonPredicate.Operator] = [.equalTo, .notEqualTo, .greaterThan, .greaterThanOrEqualTo, .lessThan, .lessThanOrEqualTo]
var operatorsNSNumber: [NSNumber] = []
for o in operators { operatorsNSNumber.append( NSNumber(value: o.rawValue) ) }
self.init( leftExpressions: leftExpressions,
rightExpressionAttributeType: .integer16AttributeType,
modifier: .direct,
operators: operatorsNSNumber,
options: 0 )
}
}
Uses it follows:
func setMyPetFilter() {
// We assume that myPredicateEditor is create/set in IB
// Remove whatever was configured in IB
myPredicateEditor.rowTemplates.removeAll()
let templateCompoundTypes = NSPredicateEditorRowTemplate( compoundTypes: [.and, .or, .not] )
let template1 = NSPredicateEditorRowTemplate( forKeyPath: "Animals", withValues: ["Dog", "Cat", "Hamster", "Canary"] )
let template2 = NSPredicateEditorRowTemplate( stringCompareForKeyPaths: ["PetName", "OwnerName"] )
let template3 = NSPredicateEditorRowTemplate( forKeyPath: "Legs", withValues: [2,4] )
let template4 = NSPredicateEditorRowTemplate( IntCompareForKeyPaths: ["Age", "AgeOwner"] )
myPredicateEditor.rowTemplates = [templateCompoundTypes, template1, template2, template3, template4]
}