I have a function which fetches those objects from a particular entity that fulfill a specified criterion:
func fetchWithPredicate(entityName: String, argume
To create a predicate (with a variable number of expressions) dynamically, use NSCompoundPredicate
, e.g.
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: subPredicates)
where subPredicates
is a [NSPredicate]
array, and each subpredicate
is created from the provided arguments in a loop with
NSPredicate(format: "%K == %@", key, value)
Something like this (untested):
func fetchWithPredicate(entityName: String, argumentArray: [NSObject]) -> [NSManagedObject] {
var subPredicates : [NSPredicate] = []
for i in 0.stride(to: argumentArray.count, by: 2) {
let key = argumentArray[i]
let value = argumentArray[i+1]
let subPredicate = NSPredicate(format: "%K == %@", key, value)
subPredicates.append(subPredicate)
}
let fetchRequest = NSFetchRequest(entityName: entityName)
fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: subPredicates)
// ...
}
You could use a compound predicate. I'll give you the Objective-C syntax, I'll leave the translation to Swift as an exercise...
If your keys and values are in a dictionary:
NSDictionary *conds = @{ @"key1": @"value1", @"key2", @"value2" };
NSMutableArray *predicates = [NSMutableArray arrayWithCapacity:conds.allKeys.length];
for (NSString *key in conds.allKeys)
{
[predicates addObject:[NSPredicate predicateWithFormat:@"%K == %@", key, conds[key]]];
}
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];
Swift 3
I found easiest way.
var predicate = NSPredicate(format: "key1 = %@ AND key2 = %@", value1, value2)
In your example the %K
and %@
format tokens are replaced only by the first two items of the argument array, the other items are ignored.
You have to provide all format tokens to be replaced in the string for example
NSPredicate(format: "%K == %@ AND %K == %@", argumentArray:["key1", "value1", "key2", "value2"])