2015-12-10 15 views
6

Ich habe eine Funktion, die die Objekte von einem bestimmten Unternehmen holt, die ein angegebenes Kriterium erfüllen:NSPredicate mit mehreren Argumenten und „AND Verhalten“

func fetchWithPredicate(entityName: String, argumentArray: [AnyObject]) -> [NSManagedObject] { 

    let fetchRequest = NSFetchRequest(entityName: entityName) 
    fetchRequest.predicate = NSPredicate(format: "%K == %@", argumentArray: argumentArray) 

    do { 
     return try self.managedContext.executeFetchRequest(fetchRequest) as! [NSManagedObject] 
    } catch { 
     let fetchError = error as NSError 
     print(fetchError) 
     return [NSManagedObject]() 
    } 

} 

Wenn passiere ich einen Array mit mehreren aguments (mehrere Attributnamen und Werte) scheint es, dass eine Abfrage wie folgt erstellt:

attributeName1 = value1 OR attributeName2 = value2 OR attributeName3 = value3 OR... 

Ich möchte diese ORs für ANDs ändern.

EDIT:

Das Problem war, dass es nur replacing the first two items mit "% K ==% @" war.

Also, ich muss eine NSCompoundPredicate to create a predicate dynamically erstellen.

Antwort

4

Um ein Prädikat (mit einer variablen Anzahl von Ausdrücken) dynamisch zu erstellen, verwenden NSCompoundPredicate, ersetzt werden z.B.

let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: subPredicates) 

wo subPredicates ist eine [NSPredicate] Array und jedes Prädikat wird aus den bereitgestellten Argumente in einer Schleife erstellt mit

NSPredicate(format: "%K == %@", key, value) 

Etwas Ähnliches (nicht getestet):

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) 

    // ... 
} 
9

In Ihrem Beispiel des %K und %@ Format Token ersetzt nur durch die ersten beiden Elemente des Arguments Array, werden die anderen Elemente ignoriert.

Sie haben alle Format-Token zu schaffen, in der Schnur zum Beispiel

NSPredicate(format: "%K == %@ AND %K == %@", argumentArray:["key1", "value1", "key2", "value2"]) 
+0

Es ist wahr, es war nur die ersten beiden Elemente zu ersetzen. Vielen Dank! – angeldev

3

Sie könnte ein zusammengesetztes Prädikat verwenden. Ich gebe Ihnen die Objective-C-Syntax, ich werde die Übersetzung Swift als Übung verlassen ...

Wenn Sie Ihre Schlüssel und Werte sind in einem Wörterbuch:

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]; 
0

Swift 3

Ich fand den einfachsten Weg.

var predicate = NSPredicate(format: "key1 = %@ AND key2 = %@", value1, value2) 
Verwandte Themen