6

I'm trying to filter a UITableView's data using a UISearchDisplayController and NSCompoundPredicate. I have a custom cell with 3 UILabels that I want to all be filtered within the search, hence the NSCompoundPredicate.

  // Filter the array using NSPredicate(s)

  NSPredicate *predicateName = [NSPredicate predicateWithFormat:@"SELF.productName contains[c] %@", searchText];
  NSPredicate *predicateManufacturer = [NSPredicate predicateWithFormat:@"SELF.productManufacturer contains[c] %@", searchText];
  NSPredicate *predicateNumber = [NSPredicate predicateWithFormat:@"SELF.numberOfDocuments contains[c] %@",searchText];

  // Add the predicates to the NSArray

  NSArray *subPredicates = [[NSArray alloc] initWithObjects:predicateName, predicateManufacturer, predicateNumber, nil];

  NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];

However, when I do this, the compiler warns me:

Incompatible pointer types initializing 'NSCompoundPredicate *_strong' with an expression of type 'NSPredicate *'

Every example I've seen online does this exact same thing, so I'm confused. The NSCompoundPredicate orPredicateWithSubpredicates: method takes an (NSArray *) in the last parameter, so I'm REALLY confused.

What's wrong?

Bhavin Ramani
  • 3,221
  • 5
  • 30
  • 41
hedrick
  • 211
  • 4
  • 13

3 Answers3

13

orPredicateWithSubpredicates: is defined to return an NSPredicate*. You should be able to change your last line of code to:

NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];

... and still have all of the compoundPredicates applied.

J Shapiro
  • 3,861
  • 1
  • 19
  • 29
13

First of all, using "contains" is very slow, consider mayber "beginswith"? Second, what you want is:

NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];

Three, you could've just done something like:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.productName beginswith[cd] %@ OR SELF.productManufacturer contains[cd] %@", searchText, searchText];
mdomans
  • 1,305
  • 12
  • 18
  • I tried doing this exact thing earlier but was getting crashes - I suppose that's the cost of working for ~15 straight hours on no sleep :) – hedrick Nov 30 '12 at 14:57
0

Here's an useful method i created based on the answers above (which i thank very much!)

It allows to create an NSPredicate dynamically, by sending an array of filter items and a string which represents the search criteria.

In the original case, the search criteria changes, so it should be an array instead of a string. But it may be helpful anyway

- (NSPredicate *)dynamicPredicate:(NSArray *)array withSearchCriteria:(NSString *)searchCriteria
{
    NSArray *subPredicates = [[NSArray alloc] init];
    NSMutableArray *subPredicatesAux = [[NSMutableArray alloc] init];
    NSPredicate *predicate;

    for( int i=0; i<array.count; i++ )
    {
        predicate = [NSPredicate predicateWithFormat:searchCriteria, array[i]];
        [subPredicatesAux addObject:predicate];
    }

    subPredicates = [subPredicatesAux copy];

    return [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];
}
Nahuel Roldan
  • 633
  • 8
  • 13