Reputation: 6077
I've seen many question here on StackOverflow but most of them were unanswered. I created an App that uses CoreData. To access the datas you have to click on the proper UITableView cell, where the cell name (textLabel) came from the Core Data attributes like that
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NSManagedObject *data = [self.datas objectAtIndex:indexPath.row];
[cell.textLabel setText:[NSString stringWithFormat:@"%@", [data valueForKey:@"name"]]];
[cell.detailTextLabel setText:nil];
}
After that i followed many tutorials about how to add a UISearchBar but always the app crashed because he couldn't match the UISearchBar text with the information stored in the Core Data that are used for the textLabel of the cell (that should be filtered)
For filtering i used this method found on the net:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{ // searchDati = array where i'm supposed to store the filtered rows
/* datas was created like this:
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Data"];
self.datas = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy]; to manage the Core Data i suppose.*/
[_searchDati removeAllObjects];
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", searchText];
_searchDati = [NSMutableArray arrayWithArray:[_datas filteredArrayUsingPredicate:resultPredicate]];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
Can you tell me how should i proceed? If it's difficult to provide a code could you at least tell me if there's a simple way to let the UISearchBar interact with the Core Data (so that i'll check on the net) or what i should do. Thanks in advance
Upvotes: 0
Views: 490
Reputation: 1931
Let's start with your invocation of CoreData, and then once that's working you can move onto querying it and responding from the search bar.
Since the UITableViewControllerDelegate protocol methods expect an extremely snappy response, standard practice is to fetch the data you need from your database and store it in a class variable, then have the tableview:cellForRowAtIndexPath: methods load their data from the class variable as needed.
When you make changes to the data, you update the class variable, and can call reloadData: on the tableView to have the interface catch up (view is not model...)
Start with configuring a proper fetch request, and loading the response into a NSMutableArray class variable. An example looks like this:
- (void)loadFiltersFromStore {
_enabledFilters = nil;
AppDelegate* delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext* moc = [delegate managedObjectContext];
NSEntityDescription* description = [NSEntityDescription entityForName:@"Filter" inManagedObjectContext:moc];
NSSortDescriptor* descriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:description];
[request setSortDescriptors:[NSArray arrayWithObject:descriptor]];
NSError *error;
_enabledFilters = [NSMutableArray arrayWithArray:[moc executeFetchRequest:request error:&error]];
if (error) {
NSLog(@"%@",error.localizedDescription);
}
}
Now you have some data fetched and present in a class variable (in this example that variable is an NSMutableArray called "enabledFilters", and it contains multiple instances of an NSManagedObject called "Filter")
Now you can access that data for your tableView to consume like so:
FreeCell* cell = [cv dequeueReusableCellWithReuseIdentifier:@"oneCell" forIndexPath:indexPath];
Filter* thisFilter = (Filter*)[_enabledFilters objectAtIndex:indexPath.row];
cell.label.text = thisFilter.name;
cell.label.backgroundColor = [UIColor clearColor];
NSString*targetName = thisFilter.imageName;
UIImage *image = [UIImage imageNamed:targetName];
cell.image.image = image;
BOOL purchased = (BOOL)[[NSUserDefaults standardUserDefaults] valueForKey:k_upgradePurchased];
if ([thisFilter.paidOrFree isEqual: @"free"]) {
cell.lockImage.hidden = YES;
}
else if (purchased) {
cell.lockImage.hidden = YES;
}
else {
cell.lockImage.hidden = NO;
}
return cell;
I purposely setup this table view so that the row will always correspond to the index of an object in _enabledFilters. You don't have to do that, but it is pretty common practice.
Now you can access the attributes for each instance of your NSManagedObject with simple 'dot' accessors. In that example, I'm pulling the values stored in three different attributes (.name .imageName and .paidOrFree) and using them to configure the specific cell.
Get your underlying CoreData working properly first, and the searchBar problem will become far more approachable.
Upvotes: 1