2012-05-16 18 views
18

Tôi cố gắng để sử dụng một UISearchBar để truy vấn nhiều thuộc tính của một NSManagedObject Tôi có một NSManagedObject gọi Person, mỗi người đều có một tài sản namesocialSecurity. Ngay bây giờ mã của tôi có thể thực hiện tìm kiếm (tìm nạp) cho một trong các thuộc tính này hoặc thuộc tính kia, nhưng không phải cả hai cùng một lúc.iOS CoreData NSPredicate để truy vấn nhiều thuộc tính cùng một lúc

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

Tôi không biết làm thế nào để đưa cả hai thuộc tính vào tuyên bố này ...

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

Bất kỳ sự giúp đỡ hay ý tưởng sẽ được đánh giá rất nhiều.

Trả lời

26

Bạn có thể nối nhiều cụm từ tìm kiếm trong một NSPredicate bằng cách sử dụng toán hạng boolean thông thường như AND/OR.

Một cái gì đó như thế này nên làm các trick.

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

Hy vọng rằng sẽ giúp :)

+1

if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat: @ "(fullName chứa [cd]% @) || (socialSecurity chứa [cd]% @) ", truy vấn, truy vấn]; – OscarTheGrouch

31

Bạn có thể sử dụng một NSCompoundPredicate.

Như thế này:

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; 

có một NSCompoundPredicate cho AND quá: andPredicateWithSubpredicates:

+2

+1 để sử dụng NSCompoundPredicate. – CaptainRedmuff

+0

NSArray * subPredicates = @ [predicateName, predicateSSID]; Tôi thích Cú pháp NSArray C 2.0 Mục tiêu, Chỉ nói –

4

Để tránh những cảnh báo loại con trỏ không tương thích khởi 'NSCompoundPredicate * _strong' với một biểu hiện của loại 'NSPredicate *', thay thế các mục sau:

NSCompoundPredicate * predicate = [NSCompoundPredicate orPredicateWithSubPredicates:subPredicates]; 

với điều này:

NSPredicate * predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates]; 

Nguồn: NSCompoundPredicate

1

Fraser Hess qua tại CISMGF.com có ​​một ví dụ tìm kiếm tuyệt vời. Bạn có thể đọc bài tại http://www.cimgf.com/2008/11/25/adding-itunes-style-search-to-your-core-data-application/

Mã của tôi dựa trên các bài viết là:

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

Đối Swift:

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

giải pháp hoàn hảo cho 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

bổ sung @ Câu trả lời của Matthias, bạn cũng có thể sử dụng NSCompoundPredicate cho các hoạt động AND của bạn như thế này.

obj-C - VÀ

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

Swift - VÀ

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

Swift 3 - VÀ

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

này có thể được sử dụng ful nếu bạn muốn tìm kiếm nhiều thuộc tính cho bất cứ điều gì phù hợp (ví dụ 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]; 

Sau đó, bạn có thể sử dụng này, ví dụ, để lọc một loạt các từ điển:

NSArray *results = [bigArray filteredArrayUsingPredicate:search]; 

(các BEGINSWITH [cd] không có phép thuật, chỉ có nghĩa là nó sẽ khớp với sự khởi đầu của các chuỗi và không phân biệt chữ hoa chữ thường. Thay đổi khi cần cho tiêu chí đối sánh của bạn.)

Các vấn đề liên quan