В наличии UITableView, контент которой заполняется из Core Data при помощи fetchedResultsController'а:
- (NSFetchedResultsController *) fetchedResultsController
{
NSLog(@"fetchedResultsController");
if (fetchedResultsController != nil)
{
return fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Client"
inManagedObjectContext:[[PTDataManager sharedManager] managedObjectContext]];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"agency_server_id == %@", agency.server_id];
fetchRequest.predicate = predicate;
NSSortDescriptor *sortByName1Descriptor = [[NSSortDescriptor alloc] initWithKey:@"lastname" ascending:YES];
NSSortDescriptor *sortByName2Descriptor = [[NSSortDescriptor alloc] initWithKey:@"firstname" ascending:YES];
NSSortDescriptor *sortByName3Descriptor = [[NSSortDescriptor alloc] initWithKey:@"middlename" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortByName1Descriptor, sortByName2Descriptor, sortByName3Descriptor, nil];
fetchRequest.sortDescriptors = sortDescriptors;
fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:[[PTDataManager sharedManager] managedObjectContext] sectionNameKeyPath:nil cacheName:nil];
fetchedResultsController.delegate = self;
return fetchedResultsController;
}
другие делегатские методы не реализованы так как таблица заполняется один раз, при входе во viewController и больше не меняется. Стоит задача реализовать поиск по контенту таблицы с отображением в таблице только результатов соответствующих значениям введенным в searchBar. Реализовываю метод:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self reloadTableView];
}
и соответственно триггеруемый метод для отображения в таблице:
- (void)reloadTableView
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Client"
inManagedObjectContext:[[PTDataManager sharedManager] managedObjectContext]];
[fetchRequest setEntity:entity];
NSPredicate *filterPredicate;
NSString *searchString = self.searchBar.text;
NSMutableArray *predicateArray = [[NSMutableArray alloc] init];
[predicateArray addObject:[NSPredicate predicateWithFormat:@"agency_server_id CONTAINS[cd] %@", agency.server_id]];
[predicateArray addObject:[NSPredicate predicateWithFormat:@"firstname CONTAINS[cd] %@", searchString]];
[predicateArray addObject:[NSPredicate predicateWithFormat:@"lastname CONTAINS[cd] %@", searchString]];
[predicateArray addObject:[NSPredicate predicateWithFormat:@"middlename CONTAINS[cd] %@", searchString]];
filterPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicateArray];
[fetchRequest setPredicate:filterPredicate];
NSSortDescriptor *sortByName1Descriptor = [[NSSortDescriptor alloc] initWithKey:@"lastname" ascending:YES];
NSSortDescriptor *sortByName2Descriptor = [[NSSortDescriptor alloc] initWithKey:@"firstname" ascending:YES];
NSSortDescriptor *sortByName3Descriptor = [[NSSortDescriptor alloc] initWithKey:@"middlename" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortByName1Descriptor, sortByName2Descriptor, sortByName3Descriptor, nil];
fetchRequest.sortDescriptors = sortDescriptors;
fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:[[PTDataManager sharedManager] managedObjectContext] sectionNameKeyPath:nil cacheName:nil];
fetchedResultsController.delegate = self;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", [error localizedDescription], [error localizedFailureReason]);
abort();
};
[self.clientsTableView reloadData];
}
который похож на fetchedResultsController но как видно имеется отличия в ограничении выборки. Проблема в том, что в таком виде вызов -reloadTableView дергает и сам fetchedResultsController, в результате фетч меняется в процессе ввода символов в searchBar. В таблице появляется все что вытянул fetchedResultsController и плюс все остальное что совпадает с содержимым searchBarа. Визуально: при вводе символов в поле поиска таблица не сокращает количество результатов а увеличивает.
Вопрос:
на каком этапе реализации поиска по уже фетченой выборке я делаю ошибку? Могу ли я как-то изменить вторичный фетч для поиска по уже полученным из первичного фетча результатам?
Ответ
Вопрос решился через составной предикат с использованием +orPredicateWithSubpredicates: и +andPredicateWithSubpredicates:
NSPredicate *orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:firstPredicate, secondPredicate, nil]];
NSPredicate *andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:thirdPredicate, fourthPredicate, nil]];
NSPredicate *finalPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:orPredicate, andPredicate, nil]];
[fetchRequest setPredicate:finalPredicate];
В таком виде через AND сохраняется результат предварительного фетча и через дополнительные OR происходит его фильтрация согласно критериям поиска
Комментариев нет:
Отправить комментарий