Search code examples
iosobjective-cuitableviewnspredicateuisearchdisplaycontroller

NSPredicate to Search Collection


I have a tableview with a search bar. I was able to use NSPredicate to search the tableview when I add the items to another array:

for(head in items){
   [desc addObject:head.DESC];
   [category addObject:head.CATEGORY];
 }

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
   NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"self CONTAINS[cd] %@", searchText];
searchResults = [desc filteredArrayUsingPredicate:resultPredicate];
}

Now I want to keep the collection together so that a tableView didSelectRowAtIndexPath will be able to use the category object.

I load my table view like this:

for (int i = 0; i < [items count]; i++){
    head = [items objectAtIndex:indexPath.row];
    labelName.text = head.DESC;

How can I get my NSPredicate to search the collection for head.DESC?

 #pragma mark Search Results
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
  {
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"self CONTAINS[cd] %@", searchText];
searchResults = [items filteredArrayUsingPredicate:resultPredicate];
}

Currently, I am getting this exception when running the above code.

reason: 'Can't use in/contains operator with collection <Order: 0x7b22e900> (not a collection)'

Solution

  • I think I understand your question. You want to be able to filter your items array (which is a bunch of heads) by the DESC property. How about using blocks?

    - (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
    {
      NSPredicate *resultPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
          return [[evaluatedObject DESC] containsString:searchText];
        }];
    
      searchResults = [items filteredArrayUsingPredicate:resultPredicate];
    }
    

    If your Order object defines DESC as a @property (or is otherwise KVC Compliant), you'll be able to just access it directly. This should work:

    - (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
    {
      NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"self.DESC CONTAINS[cd] %@", searchText];
      searchResults = [items filteredArrayUsingPredicate:resultPredicate];
    }