kevintuhumury / itvdb

An Objective-C wrapper around the TVDB (http://thetvdb.com) XML API for use in iOS (with ARC enabled) and OSX apps.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Asynchronous Call to search for show

dehlen opened this issue · comments

Hello,

first of all thank you so much for this library. It saved me a lot of time. Unfortunately I came to a problem and hope you can help me out here. I am using the method

NSMutableArray *shows = [TVDbShow findByName:name];

to give the user the ability to search for a show.

Now i like to implement kind of an autocomplete ability to show all tv-shows returning while the user is typing. Because the API call can take some time the search functionality is really slow. Is there a chance to make the findByName method async ?

Currently this is what I am doing: In my UISearchResultsUpdatingDelegate I call my method to get the corresponding shows and then show them in my tableview:

#pragma mark - UISearchResultsUpdating

-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {

    NSString *searchString = [self.searchController.searchBar text];

    [self updateFilteredContentForName:searchString];

    if (self.searchController.searchResultsController) {
        DEResultsViewController *vc = (DEResultsViewController *)self.searchController.searchResultsController;
        vc.searchResults = self.searchResults;
        [vc.tableView reloadData];
    }

}
- (void)updateFilteredContentForName:(NSString *)name {

    [self.searchResults removeAllObjects]; // First clear the filtered array.

    // Update the filtered array based on the search text and scope.
    if (name == nil || [name length] == 0) {
        return;
    }
    NSMutableArray *shows = [TVDbShow findByName:name];
    self.searchResults = shows;
}

Nevermind got it working by myself using a NSOperationQueue. I had some difficulties getting this right. Not the method findByName needs to work asynchronously itself but the call should not block the UI which is why I used the NSOperationQueue and wait for the call to finish. This is how i managed it to work for someone having similar problems:

-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {

    NSString *searchString = [self.searchController.searchBar text];

    if  (searchString.length > 0 && searchString != nil)
    {
        [self.searchQueue cancelAllOperations];
        [self.searchQueue addOperationWithBlock:^{

            NSMutableArray *shows = [TVDbShow findByName:searchString];

            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                // Modify your instance variables here on the main
                // UI thread.
                [self.searchResults removeAllObjects];
                self.searchResults = shows;

                // Reload your search results table data.
                if (self.searchController.searchResultsController) {
                    DEResultsViewController *vc = (DEResultsViewController *)self.searchController.searchResultsController;
                    vc.searchResults = self.searchResults;
                    [vc.tableView reloadData];
                }
            }];
        }];

    }
    else
    {
        [self.searchResults removeAllObjects];
    }
}