如何使用NSFetchedResultsController和UISearchDisplayController

时间:2010-02-03 17:02:39

标签: iphone core-data nsfetchedresultscontroller uisearchdisplaycontroller

我一直在使用核心数据创建iPhone应用程序。

首先,使用NSFetchedResultsController和UISearchDisplayController一起获取结果是否有意义?你会推荐别的吗?

我一直在尝试很长时间组合NSFetchedResultController和UISearchDisplayController。我一直在考虑在(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption方法中将NSPredicate设置为UIViewController的NSFetchedResultController。但这并没有那么好。

那么,您知道如何为我的问题实施解决方案吗?非常感谢您发布答案或指向优秀教程的链接。

修改

这是我的代码。 UISearchDisplayDelegate方法调用应在NSFetchedResultController中设置谓词的方法(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope。我还添加了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;
} 

3 个答案:

答案 0 :(得分:21)

瞥见你的代码吧。我遇到了使用此方法更改搜索的问题。修复:清除缓存!

假设您启动了获取的结果控制器,如下所示。请注意cacheName属性。

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:[self fetchRequest] managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"UserSearch"];

在更改谓词时,只需添加:

 [NSFetchedResultsController deleteCacheWithName:@"UserSearch"];

像魔法一样,它会很好地运作。

您还需要监控搜索显示控制器何时结束搜索,并擦除谓词。

虽然这个帖子看起来已经死了,但我在google上找到了它,所以也许那里有人会使用它。 :)

答案 1 :(得分:7)

根据文档,您要么想使用谓词将结果过滤到数组中,要么重新初始化fetchedResultsController。

  

重要提示:您不得修改   你有了获取请求   初始化控制器。对于   例如,你不能改变   谓词或排序顺序。

     

- NSFetchedResultsController

(我会评论闲置的答案,但我是无业力的。)

答案 2 :(得分:1)

听起来你只对获取和显示对象感兴趣。在这种情况下,您不使用搜索显示控制器。搜索显示控制器与搜索栏一起使用,以帮助允许用户输入的内容文本搜索。

通常,您使用获取的结果控制器来帮助您实现表视图数据源和委托方法。此外,您还为获取的结果控制器创建并使用获取请求。这是所有样板(请参阅Apple在您选择“使用核心数据进行存储”选项创建新项目时提供的模板代码。)

您可以在获取请求中创建并指定谓词。这将允许您过滤表格显示的对象。例如:

// only fetch objects with myAttribute set to someValue
NSPredicate *pred = [NSPredicate predicateWithFormat:@"myAttribute == %@",someValue];
[fetchRequest setPredicate:pred];