14

CoreDataを使用してiPhoneアプリを作成しています。

まず、NSFetchedResultsControllerとUISearchDisplayControllerを一緒に使用して結果をフェッチすることは理にかなっていますか?他に何かお勧めしますか?

NSFetchedResultControllerとUISearchDisplayControllerを組み合わせてかなり長い間試してきました。メソッドのNSPredicateをUIViewControllerのNSFetchedResultControllerに設定することを考えていました(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption。しかし、これはうまく機能していません。

それで、私の問題の解決策を実装する方法について何か考えがありますか?回答や優れたチュートリアルへのリンクを投稿していただき、ありがとうございます。

編集

これが私のコードです。(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scopeUISearchDisplayDelegateメソッドは、NSFetchedResultControllerで述語を設定する必要があるメソッドを呼び出します。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;
} 
4

3 に答える 3

21

あなたのコードをちらっと見て、その権利があります。この方法を使用して検索を変更すると、問題が発生しました。修正:キャッシュをクリアしてください!

フェッチした結果コントローラーを次のように開始したとします。cacheNameプロパティに注意してください。

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

述語を変更するときは、次を追加するだけです。

 [NSFetchedResultsController deleteCacheWithName:@"UserSearch"];

魔法のように、それはうまく機能します。

また、検索表示コントローラーが検索を終了するタイミングを監視し、述語をワイプすることもできます。

このスレッドは死んでいるように見えますが、私はグーグルで見つけたので、おそらく誰かがこれを利用するでしょう。:)

于 2010-03-04T19:29:35.167 に答える
7

ドキュメントによると、述語を使用して結果を配列にフィルタリングするか、fetchedResultsControllerを再初期化する必要があります。

重要:コントローラーを初期化した後は、フェッチ要求を変更しないでください。たとえば、述語やソート順を変更してはなりません。

--NSFetchedResultsController _

(アイドルの答えについてコメントしますが、私はカルマがありません。)

于 2010-07-13T20:12:30.827 に答える
1

オブジェクトのフェッチと表示に関心があるようです。この場合、検索表示コントローラーは使用しません。検索表示コントローラーは検索バーとともに使用され、ユーザーが入力したコンテンツのテキスト検索を可能にします。

通常、フェッチされた結果コントローラーを使用して、テーブルビューのデータソースとデリゲートメソッドの実装を支援します。また、フェッチされた結果コントローラーのフェッチ要求を作成して使用します。これはすべて定型文です([ストレージにCore Dataを使用する]オプションを選択して新しいプロジェクトを作成するときにAppleが提供するテンプレートコードを参照してください)。

述部を作成および指定できるのは、フェッチ要求内です。これにより、テーブルに表示されるオブジェクトをフィルタリングできます。例えば:

// only fetch objects with myAttribute set to someValue
NSPredicate *pred = [NSPredicate predicateWithFormat:@"myAttribute == %@",someValue];
[fetchRequest setPredicate:pred];
于 2010-02-03T18:47:45.627 に答える