Ho creato un'app per iPhone utilizzando i dati principali.Come utilizzare NSFetchedResultsController e UISearchDisplayController
Prima di tutto, ha senso utilizzare un NSFetchedResultsController e un UISearchDisplayController insieme per recuperare il risultato? Consiglieresti qualcos'altro?
Ho cercato a lungo unendo un NSFetchedResultController e un UISearchDisplayController. Stavo pensando di impostare un NSPredicate nel metodo (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
per NSFetchedResultController di UIViewController. Ma non sta funzionando così bene.
Quindi, hai idea di come implementare una soluzione per il mio problema? Grazie per aver pubblicato risposte o collegamenti a buoni tutorial.
EDIT
Ecco il mio codice. I metodi UISearchDisplayDelegate chiamano il metodo (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
che dovrebbe impostare il predicato in NSFetchedResultController. Ho anche aggiunto il codice di NSFetchedResultController.
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
[self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSString *query = self.searchDisplayController.searchBar.text;
if (query && query.length) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Name contains[cd] %@", query];
[fetchedResultsController.fetchRequest setPredicate:predicate];
}
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
// Handle error
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
}
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
/*
Set up the fetched results controller.
*/
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
return fetchedResultsController;
}
Questa soluzione funziona, ma è piuttosto costosa, costringendo il controller dei risultati recuperato in numerosi viaggi nell'archivio permanente. Inoltre, se non intendi utilizzare la cache, perché specificarne una? Basta passare nil. Una soluzione molto migliore, tuttavia, è ciò che @psuedonick suggerisce: Lascia che il fetchedResultsController esegua le operazioni migliori, ovvero gestisce i risultati recuperati e usa filteredArrayUsingPredicate: su fetchedObjects per popolare filteredListContent. –
Per chiarire, se si utilizza la soluzione che descrivo, si * dovrebbe * specificare una cache: il controller dei risultati recuperato ne avrà bisogno per archiviare gli oggetti fetched in modo che possano essere efficacemente cercati da filteredArrayUsingPredicate: –
Grazie Elise, penso che la tua via sia la strada da percorrere Concluderò i passaggi per implementare il controller di visualizzazione della ricerca in un controller di visualizzazione tabella in un altro post successivo. Mi ci vuole così tanto tempo per cercare una buona pratica su questo argomento. – Philip007