Question

I want to search the AppStore based on what a user types into search.

I have set up the following code to do this, which will amend the search on each character being entered to narrow the search.

However, as there is a request made as every character entered and these can take time to return, the UI can become unresponsive.

I would like to a) understand how I can stop the UI becoming unresponsive (I fear I am bringing the running back onto the main thread with performselectoronmainthread?), and b) would it be prudent to cancel the previous lookup as each character is entered, thus using the new narrower search, and if so how to do this?

Thanks in advance.

Update: I have tried the suggestion as made by Emilie Lessard, and whilst I can see the logic, I am unable to get this to benefit the app. See response below.

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)

-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
    if(text.length == 0)
    {
        jsonResults = nil;
        [self.tableView reloadData];
    }
    else
    {
        jsonResults = nil;
        [self.tableView reloadData];
        NSURL *searchUrl = [NSURL URLWithString:[NSString stringWithFormat:@"https://itunes.apple.com/search?term=%@&country=gb&entity=software",text]];
         dispatch_async(kBgQueue, ^{
         NSData* data = [NSData dataWithContentsOfURL:searchUrl];
         [self performSelectorOnMainThread:@selector(fetchedData:)
         withObject:data waitUntilDone:NO];
         });
    }
}


-(void)fetchedData:(NSData *)responseData{
    NSError* error;
    NSDictionary* json = [NSJSONSerialization
                          JSONObjectWithData:responseData
                          options:kNilOptions
                          error:&error];
    jsonResults = [json objectForKey:@"results"];
    [self.tableView reloadData];
}
Was it helpful?

Solution

You need to use dispatch_async()

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //Do the computing-research

     dispatch_async(dispatch_get_main_queue(), ^{
        //do UI update here
    });
});

By using a global queue, the UI of your app won't get blocked. Once all info has been computed/received, it is MANDATORY that you go back to the main thread (by using dispatch_async(dispatch_get_main_queue()) for all UI updates or you'll end up with hard-to-debug crashes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top