I continue to read that i should use [_context performBlock]:^...
to do asynchronous searches when using core-data. What i cant figuered out for the life of me is how to subscribe to the end or the complete event sort of speak of this block. In other words in my code I'm using a UIActivityIndicatorView
prior to my fetch of data and i would like to remove this view once the data has been retrieve. However I don't understand how to properly accomplish this.
In the past i have used dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{...
and then implemented
dispatch_async(dispatch_get_main_queue(), ^(void) {
to know when the que is finish doing the background processing.
I might have this all completely wrong , but i figuered i ask the question. What delegate do i need to implement or what method do i need to subscribe to. To know when my fetch is complete that i have just executed within the performBlock:
Again my end goal is to set a UIActivityIndicatorView visible before the fetch , fetch the data and set it back to not visible. thanks in advance for any help you guys can offer.
**update**
I'm required to do the search asynchronously due to the large amount of records that i have to search through. I have roughly 195k records and so there is like a 1 to 2 second lag if i try to do this in the main thread when the user start to type letters in the search bar. Hence the reason why i throw up a UIActivityIndicatorView
and then I do the search on the background thread and update the main thread when I'm done.
This is the code I'm using to acomplish this.
@property (strong, nonatomic) NSArray *filteredLocations;
@property (strong, nonatomic) NSArray * locationsFiltered;
//returns the search for this particular search.
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
if ([searchString length ]>= 3) {
[self searchForText:searchString];
return YES;
}
else{
self.filteredLocations = nil;
return NO;
}
//return YES;
}
- (void)searchForText:(NSString *)searchText
{
if (self.context && self.isSearching == FALSE)
{
//[searchController ]
//[self.searchDisplayController.searchResultsTableView.]
self.isSearching = TRUE;
NSString *predicateFormat = @"%K BEGINSWITH[cd] %@ and state ==%@";
NSString *searchAttribute = @"name";
self.filteredLocations = nil;
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat, searchAttribute, searchText,Searchstate];
[self.searchFetchRequest setPredicate:predicate];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
if (self.spinnerShowing ==FALSE) {
spinner.center = CGPointMake(160, 190);
spinner.hidesWhenStopped = YES;
spinner.color = [UIColor grayColor];
[self.view addSubview:spinner];
//self.spinnerShowing = ;
[spinner startAnimating];
}
[_context performBlock:^(void){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError *error = nil;
self.filteredLocations = [self.managedObjectContext executeFetchRequest:self.searchFetchRequest error:&error];
NSLog(@"this is how many items are in the filtered locations at this time %i", [_filteredLocations count]);
if (error)
{
NSLog(@"searchFetchRequest failed: %@",[error localizedDescription]);
}
dispatch_async(dispatch_get_main_queue(), ^(void) {
NSLog(@"stopping the spinner now.");
self.spinnerShowing = FALSE;
[spinner stopAnimating];
[spinner hidesWhenStopped];
self.isSearching = FALSE;
//self.searchDisplayController.searchResultsTableView.hidden = NO;
// [searchController reloadData];
[self.searchDisplayController.searchResultsTableView reloadData];
});
});
}];
}
}