2012-05-16 54 views
18

我試圖用一個UISearchBar查詢的NSManagedObject 多個屬性查詢多個屬性我有一個名爲PersonNSManagedObject,每個人都有一個namesocialSecurity財產。現在我的代碼可以爲其中一個屬性或其他屬性執行搜索(提取),但不能同時執行這兩個屬性。的iOS CoreData NSPredicate來一次

- (void) performFetch 
{  
    [NSFetchedResultsController deleteCacheWithName:@"Master"]; 

    // Init a fetch request 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"MainObject" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    // Apply an ascending sort for the color items 
    //NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Term" ascending:YES selector:nil]; 
    NSSortDescriptor *sortDescriptor; 
    sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"fullName" ascending:YES selector:@selector(caseInsensitiveCompare:)];  

    NSArray *descriptors = [NSArray arrayWithObject:sortDescriptor]; 
    [fetchRequest setSortDescriptors:descriptors]; 

    // Recover query 
    NSString *query = self.searchDisplayController.searchBar.text; 
    //if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"Term contains[cd] %@", query]; 
    if(searchValue==1) 
    { 
     if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name contains[cd] %@", query]; 
    } 
    else { 
     if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"socialSecurity contains[cd] %@", query]; 
    }   

    // Init the fetched results controller 
    NSError *error; 
    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"pLLetter" cacheName:nil]; 

    self.fetchedResultsController.delegate = self; 

    if (![[self fetchedResultsController] performFetch:&error]) NSLog(@"Error: %@", [error localizedDescription]); 

    [self.tableView reloadData]; 
} 

我不知道如何把兩個屬性到本聲明

if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name contains[cd] %@", query]; 

任何幫助或想法,將不勝感激。

回答

26

可以使用通常的布爾操作數,如AND/OR追加在NSPredicate多個搜索詞。

像這樣的東西應該做的伎倆。

[NSPredicate predicateWithFormat:@"name contains[cd] %@ OR ssid contains[cd] %@", query, query]; 

希望幫助:)

+1

if(query && query.length)fetchRequest.predicate = [NSPredicate predicateWithFormat:@「(fullName contains [cd]%@)||(socialSecurity contains [cd]%@) 「,查詢,查詢]; – OscarTheGrouch

31

你可以使用一個NSCompoundPredicate

像這樣:

NSPredicate *predicateName = [NSPredicate predicateWithFormat:@"name contains[cd] %@", query]; 
NSPredicate *predicateSSID = [NSPredicate predicateWithFormat:@"socialSecurity contains[cd] %@", query]; 
NSArray *subPredicates = [NSArray arrayWithObjects:predicateName, predicateSSID, nil]; 

NSPredicate *orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates]; 

request.predicate = orPredicate; 

存在用於AND太一個NSCompoundPredicateandPredicateWithSubpredicates:

+2

+1使用NSCompoundPredicate。 – CaptainRedmuff

+0

NSArray * subPredicates = @ [predicateName,predicateSSID];我喜歡Objective C 2.0 NSArray語法,只是說 –

4

爲了避免該警告不相容指針類型初始化 'NSCompoundPredicate * _strong' 與類型的表達式 'NSPredicate *'替換如下:

NSCompoundPredicate * predicate = [NSCompoundPredicate orPredicateWithSubPredicates:subPredicates]; 

本:

NSPredicate * predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates]; 

來源:NSCompoundPredicate

1

弗雷澤在赫斯在CISMGF.com有一個偉大的搜索例子。您可以根據關閉後閱讀http://www.cimgf.com/2008/11/25/adding-itunes-style-search-to-your-core-data-application/

我的代碼的帖子是:

NSArray *searchTerms = [searchText componentsSeparatedByString:@" "]; 
if ([searchTerms count] == 1) { // Search in name and description 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(name contains[cd] %@) OR (desc contains[cd] %@)", searchText, searchText]; 
    [self.searchFetchedResultsController.fetchRequest setPredicate:predicate]; 
} else { // Search in name and description for multiple words 
    NSMutableArray *subPredicates = [[NSMutableArray alloc] init]; 
    for (NSString *term in searchTerms) { 
     NSPredicate *pred = [NSPredicate predicateWithFormat:@"(name contains[cd] %@) OR (desc contains[cd] %@)", term, term]; 
     [subPredicates addObject:pred]; 
    } 
    NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates]; 
    [self.searchFetchedResultsController.fetchRequest setPredicate:predicate]; 
} 
0

對於斯威夫特:

var predicate = NSCompoundPredicate(
     type: .AndPredicateType, 
     subpredicates: [predicate1, predicate2] 
    ) 
4

爲Swift2

let request = NSFetchRequest(entityName: "Location") 
let subPredicate1 = NSPredicate(format: "(name = %@)", searchString) 
let subPredicate2 = NSPredicate(format: "(street = %@)", searchString) 
let subPredicate3 = NSPredicate(format: "(city = %@)", searchString) 

request.predicate = NSCompoundPredicate(type: .OrPredicateType, subpredicates: [subPredicate1, subPredicate2, subPredicate3]) 
8

加成@完整的解決方案Matthias的回答是,你也可以使用NSCompoundPredicate來處理你的AND操作。

的OBJ-C - AND

NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"]; 
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"]; 
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[predicate1, predicate2]]; 

夫特 - AND

let predicate1:NSPredicate = NSPredicate(format: "X == 1") 
let predicate2:NSPredicate = NSPredicate(format: "Y == 2") 
let predicate:NSPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1,predicate2]) 

夫特3 - AND

let predicate1 = NSPredicate(format: "X == 1") 
    let predicate2 = NSPredicate(format: "Y == 2") 
    let predicateCompound = NSCompoundPredicate(type: .and, subpredicates: [predicate1,predicate2]) 
1

這可以是使用FUL如果您要搜索多個屬性的任何匹配(如UISearchControllerDelegate):

NSString *searchFor = @"foo"; 
NSArray *fields = @[@"Surname", @"FirstName", @"AKA", @"Nickname"]; // OR'd dictionary fields to search 
NSMutableArray *predicates = NSMutableArray.new; 
for (NSString *field in fields) { 
    [predicates addObject:[NSPredicate predicateWithFormat:@"(%K BEGINSWITH[cd] %@)", field, searchFor]]; 
} 
NSPredicate *search = [NSCompoundPredicate orPredicateWithSubpredicates:predicates]; 

然後,您可以使用此功能,例如,過濾詞典的數組:

NSArray *results = [bigArray filteredArrayUsingPredicate:search]; 

(該BEGINSWITH [cd]不是魔術,只是意味着它會匹配字符串的開始和不區分大小寫。 )