2013-12-17 20 views
6

Ho un array di istanze di una classe denominata Contact, che ha, tra l'altro, le seguenti proprietà:Utilizzando NSPredicate per la ricerca in array di oggetti

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

il tag classe ha le seguenti proprietà:

NSString *name; 
UIColor *color; 

Desidero utilizzare NSPredicate per cercare una stringa in qualsiasi proprietà di ogni Contact. Questo è il codice che ho:

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

Tutto funziona benissimo tranne SCOPE_TAG, non restituisce alcun valore. Non penso di usare correttamente il predicato.

NOTA: Sono nuovo con NSPredicate così mi piacerebbe sentire alcune intuizioni se quello che sto facendo non è ok

+0

non al 100% sicuro se questo è ciò che è responsabile del tuo problema, ma dovresti usare l'identificatore di formato '% K' per i keypaths invece di'% @ '. Ad esempio, la stringa di formato per "SCOPE_TAG" sarebbe "SELF.% K.name contiene [c]% @" '. – indragie

+0

Grazie per il commento. L'ho modificato in% K, ma il comportamento non è cambiato –

+0

Non ti manca l '"ANY" nella tua seconda affermazione di predicato? Penso che tu voglia controllare se qualcuno dei nomi di tag nell'array contiene il testo ... – Alexander

risposta

8

Prima di tutto, se si sostituisce un percorso chiave si dovrebbe usare %K come arg .

Inoltre, penso che manchi l'argomento ANY nella seconda query. Penso che tu voglia un risultato se qualcuno dei nomi dei tag contiene il tuo textSearch.

Per ottenere una migliore comprensione di come predicati di lavoro, avere uno sguardo alla Apple Documentation

Ho fatto un test rapido ed è ancora lavorando bene:

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

Grazie! Funziona perfettamente ora. ho fatto un errore prima, perché ho provato ad usare "ANY" e ho ottenuto un'eccezione dicendo che l'operatore non può essere usato perché non è una collezione. Questo mi ha fatto pensare che "ANY" doveva essere usato solo con array, set, ecc. . –

Problemi correlati