2013-12-17 3 views
6

ich eine Reihe von Instanzen einer Klasse Contact haben zu suchen genannt, die unter anderem hat die folgenden Eigenschaften:NSPredicate Verwendung durch Array von Objekten

NSArray *mailAddressList // Array of NSString 
NSArray *websiteList // Array of NSString 
NSArray *tags // Array of instances of Tag class 

Die Klasse-Tag die folgenden Eigenschaften hat:

NSString *name; 
UIColor *color; 

Ich möchte mit NSPredicate eine Zeichenfolge in einer beliebigen Eigenschaft von jedem Contact suchen. Dies ist der Code, den ich habe:

if([scope isEqualToString:SCOPE_MAIL] || [scope isEqualToString:SCOPE_WEBSITE]) 
{ 
    // Search through an array 
    predicate = [NSPredicate predicateWithFormat:@"ANY SELF.%@ contains[c] %@", scope, textSearch]; 
} 
else if([scope isEqualToString:SCOPE_TAG]) 
{ 
    // Search another object's property 
    predicate = [NSPredicate predicateWithFormat:@"SELF.%@.name contains[c] %@", scope, textSearch]; 
} 
else 
{ 
    // The rest of the properties are instances of NSString 
    predicate = [NSPredicate predicateWithFormat:@"SELF.%@ contains[c] %@", scope, textSearch]; 
} 

Alles funktioniert gut, außer für SCOPE_TAG, ist es keine Werte zurückgeben. Ich glaube nicht, dass ich das Prädikat richtig verwende.

HINWEIS: ich mit NSPredicate neu bin, damit ich einige Einblicke zu hören, wie wenn das, was ich tue, ist nicht ok

+0

nicht zu 100% sicher, ob dies ist, was verantwortlich für Ihr Problem, aber Sie sollten den '% K' Format-Bezeichner für Schlüsselpfade anstelle von% @' verwenden. So wäre zum Beispiel die Formatzeichenfolge für 'SCOPE_TAG'' SELF.% K.name enthält [c]% @ "'. – indragie

+0

Danke für den Kommentar. Ich habe ihn in '% K' geändert, aber das Verhalten hat sich nicht geändert –

+0

Vermissen Sie nicht die "ANY" in Ihrer zweiten Prädikat Aussage? Ich denke, Sie wollen überprüfen, ob einer der Tag-Namen in Ihrem Array den Text enthält ... – Alexander

Antwort

8

Vor allem, wenn Sie einen Schlüsselpfad ersetzen sollten Sie %K als arg verwenden .

Weiter, ich denke, Sie fehlen das ANY Argument in Ihrer zweiten Abfrage. Ich denke, Sie wollen ein Ergebnis, wenn einer der Tag-Namen Ihre textSearch enthält.

Um ein besseres Verständnis davon, wie Prädikate arbeiten, haben einen Blick auf die Apple Documentation

ich einen schnellen Test gemacht und es funktioniert immer noch gut:

NSMutableArray *arrayContacts = [NSMutableArray array]; 

{ 
    AMContact *contact = [[AMContact alloc] init]; 
    NSMutableArray *arrayTags = [NSMutableArray array]; 
    { 
     AMTags *tag = [[AMTags alloc] init]; 
     tag.name = @"Test"; 
     [arrayTags addObject:tag]; 
    } 

    { 
     AMTags *tag = [[AMTags alloc] init]; 
     tag.name = @"Te2st2"; 
     [arrayTags addObject:tag]; 
    } 

    { 
     AMTags *tag = [[AMTags alloc] init]; 
     tag.name = @"No"; 
     [arrayTags addObject:tag]; 
    } 
    contact.tags = [arrayTags copy]; 
    [arrayContacts addObject:contact]; 
} 

{ 
    AMContact *contact = [[AMContact alloc] init]; 
    NSMutableArray *arrayTags = [NSMutableArray array]; 
    { 
     AMTags *tag = [[AMTags alloc] init]; 
     tag.name = @"Test"; 
     [arrayTags addObject:tag]; 
    } 
    contact.tags = [arrayTags copy]; 
    [arrayContacts addObject:contact]; 
} 
NSPredicate *pred = [NSPredicate predicateWithFormat:@"ANY SELF.%K.name contains[c] %@", @"tags", @"Test"]; 

NSArray *result = [arrayContacts filteredArrayUsingPredicate:pred]; 

NSLog(@"%@", result); 
+0

Vielen Dank! Es funktioniert perfekt jetzt. Ich muss Ich habe vorher einen Fehler gemacht, weil ich versucht habe, 'ANY' zu verwenden und eine Exception, die besagt, dass der Operator nicht verwendet werden kann, weil es keine Sammlung ist. Dies ließ mich glauben, dass' ANY' nur für Arrays, Sets usw . –