Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using NSFetchedResultsController to with UISearchBar

I have a UISearhBarController in my app. It currently searches an online database, but I'm changing it to search a core data database instead. Its currently using this code:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{
    if (self.billingSearchBar == searchBar) {
        [self.billingSearchController filterResultsUsingString:searchText];
    }
}

- (void)filterResultsUsingString:(NSString *)filterString 
{
    self.billingSearchText = filterString;
    NSArray *billing_codes = [self billingSearch:self.billingSearchText searchType:self.billingSearchCategory];
    self.displayedBillingSearch = billing_codes;
    self.billingSearch = billing_codes; 
    [self.tableView reloadData];
}

-(NSMutableArray*)billingSearch:(NSString*)searchString searchType:(NSString*)searchType
{
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/server/20111115/60b88126/billing_search/", [self getHost]]];

    ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease];
    [request setPostValue:searchString forKey:@"query"];
    [request setPostValue:searchType forKey:@"category"];

    [request startSynchronous];
    NSError *error = [request error];
    NSString *responseString;
    if (!error) {
        responseString = [request responseString];
    }

    NSMutableArray *search_results = [[NSMutableArray alloc] init];
    NSDictionary *responseDictionary = [responseString JSONValue];

    for (id key in [responseDictionary valueForKey:@"search_results"]) {
        [search_results addObject:key];
    }
    return search_results;  
}

So I have the database setup in core data already, I just need to hook up the search/NSFetchedResults controller to it. Any easy way to do so?

like image 809
Jon Avatar asked Dec 16 '11 20:12

Jon


1 Answers

The cleanest way to do that is to use two NSFetchedResultsControllers and set the predicate on your "searching" NSFRC to be the searchText in the UISearchBar. After you decide which NSFRC to use, you just set your self.fetchedResultsController = "searching" NSFRC or the "default" NSFRC.

You can also use the same NSFRC and change the predicate, but that is not the recommended way to do it.

See comment below. If all that is changing is the predicate, one FRC is fine.

Here is sample code to get this done:

// First use the Searchbar delegate methods
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{   
    [self filterContentForSearchText:searchText];
}

-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [self filterContentForSearchText:searchBar.text];
    [searchBar resignFirstResponder];
}

// The method to change the predicate of the FRC
- (void)filterContentForSearchText:(NSString*)searchText
{
    NSString *query = searchText;
    if (query && query.length) {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[cd] %@ or department contains[cd] %@", query, query];
        [self.fetchedResultsController.fetchRequest setPredicate:predicate];
        [self.fetchedResultsController.fetchRequest setFetchLimit:100]; // Optional, but with large datasets - this helps speed lots
    }

    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
        // Handle error
        exit(-1);
    }

    [self.myTableView reloadData];
}

This should get ya started.

like image 71
LJ Wilson Avatar answered Oct 29 '22 15:10

LJ Wilson