Search code examples
objective-cios4xcode4uisearchbar

UISearchBar and NSDictionary


i want to add to my app a UISearchBar.

I have 3 NSDictionary that contains respectively 3 arrays (sorted). The 3 NSDictionaries have the same key (@"Elements"), stored in a NSMutableArray called listObjects.

At the end of the 3 dicts i have this situation:

[listObjects addObject:dictOne];
[listObjects addObject:dictTwo];
[listObjects addObject:dictThree];  

I also have a filteredListContent to store the arrays (for quick searching).

filteredListContent = [[NSMutableArray alloc] initWithCapacity: [listObjects count]];
[filteredListContent addObjectsFromArray: listObjects];

Now, the first question is: does the filteredListContent array store all the 3 dict keys from listObjects?

Then.

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope{

    [self.filteredListContents removeAllObjects]; 
    NSString *cellTitle;
    for (cellTitle in listObjects){
        NSComparisonResult result = [cellTitle compare:searchText options:NSCaseInsensitiveSearch range:NSMakeRange(0, [searchText length])];
        if (result == NSOrderedSame){
            [filteredListContents addObject:cellTitle];
        }
    }
}

I got a crash as i begin typing in

NSComparisonResult result = [cellTitle compare:searchText options:NSCaseInsensitiveSearch range:NSMakeRange(0, [searchText length])];` 

line. Is there supposed to be the key of the dict (@"Elements"), in order to search in all the 3 arrays or?

Edit

Full code

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSDictionary *dictionary = [listObjects objectAtIndex:section];
    NSArray *array = [dictionary objectForKey:@"Elements"];
    return [array count];
}


    - (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope{

        NSString *cellTitle;
        for (NSDictionary *dict in listaObjects)
        {
            NSArray *elements = [dict objectForKey: @"Elements"];
            for (NSString *cellTitle in elements)
                if ([cellTitle compare: searchText options: NSCaseInsensitiveSearch range: NSMakeRange(0, [searchText length])] = NSOrderedSame)])
                    [filteredListContent addObject: cellTitle];

        }}

    #pragma mark -
    #pragma mark UISearchDisplayController Delegate Methods

    - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{
        [self filterContentForSearchText:searchString scope:
         [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];

        // Return YES to cause the search result table view to be reloaded.
        return YES;
    }


    - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption{

        [self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope:
         [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];

        // Return YES to cause the search result table view to be reloaded.
        return YES;
    }

I got it working, but it shows the contents of all the arrays, even if i type a specific word. What am i doing wrong?


Solution

  • I don't get it. You first add the three dictionaries to filteredListContents and then you remove all objects from the array? That means the array is totally empty again.

    Then you enumerate listObjects, which only contains 3 dictionaries, and no strings, using an NSString enumerator. That doesn't make sense.

    First, there is no need to do:

    [filteredListContents addObjectsFromArray: listObjects];
    

    So remove that line. Now do something like:

    for (NSDictionary *dict in listObjects)
    {
        NSArray *elements = [dict objectForKey: @"Elements"];
        for (NSString *cellTitle in elements)
            if (cellTitle compare: searchText options: options: NSCaseInsensitiveSearch range: NSMakeRange(0, [searchText length])] = NSOrderedSame)
                [filteredListContents addObject: cellTitle];
    
    }
    

    OK, that gives you an array of equal strings. Now what? I'd expect you to collect the cells with that title, but you are not doing that here. You could, instead of storing strings, store dictionaries with the cell title as key and the cell as value. That would make the loop only one level deeper.

    As someone wiser than me once said: Show me your problem, not your solution. Then I can help you.

    The full code doesn't make any sense to me, sorry. What are you trying to collect actually?