iOS CoreData NSPredicate to query multiple properties at once

后端 未结 8 1822
刺人心
刺人心 2020-12-23 22:39

I am trying to use a UISearchBar to query multiple properties of a NSManagedObject I have a NSManagedObject called Person

相关标签:
8条回答
  • 2020-12-23 22:45

    To avoid the warning Incompatible pointer types initializing 'NSCompoundPredicate *_strong' with an expression of type 'NSPredicate *', replace the following:

    NSCompoundPredicate * predicate = [NSCompoundPredicate orPredicateWithSubPredicates:subPredicates];
    

    with this:

    NSPredicate * predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];
    

    Source: NSCompoundPredicate

    0 讨论(0)
  • 2020-12-23 22:47

    This is may be useful if you want to search multiple properties for anything that matches (eg 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];
    

    You could then use this, for example, to filter an array of dictionaries:

    NSArray *results = [bigArray filteredArrayUsingPredicate:search];
    

    (the BEGINSWITH[cd] is no magic, just means it'll match beginnings of strings and case-insensitive. Change as needed for your match criteria.)

    0 讨论(0)
  • 2020-12-23 22:48

    You could use a NSCompoundPredicate.

    Like this:

    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;
    

    there is a NSCompoundPredicate for AND too: andPredicateWithSubpredicates:

    0 讨论(0)
  • 2020-12-23 22:55

    For Swift:

    var predicate = NSCompoundPredicate(
            type: .AndPredicateType,
            subpredicates: [predicate1, predicate2]
        )
    
    0 讨论(0)
  • 2020-12-23 22:57

    Fraser Hess over at CISMGF.com has a great search example. You can read the post at http://www.cimgf.com/2008/11/25/adding-itunes-style-search-to-your-core-data-application/

    My code based off the post is:

    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 讨论(0)
  • 2020-12-23 23:00

    Addition to @Matthias's answer, you can also use NSCompoundPredicate for your AND operations like this.

    Obj-C - AND

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

    Swift - AND

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

    Swift 3 - AND

        let predicate1 = NSPredicate(format: "X == 1")
        let predicate2 = NSPredicate(format: "Y == 2")
        let predicateCompound = NSCompoundPredicate(type: .and, subpredicates: [predicate1,predicate2])
    
    0 讨论(0)
提交回复
热议问题