0

ユーザーが本を閲覧/検索してダウンロードできるアプリを開発しています。3つのUITableView、ダウンロード/検索/閲覧があります

ダウンロードされていない場合は「ダウンロード」ボタンを表示したいのですが、そうでない場合は「開く」ボタンを表示します。ダウンロードテーブルビューでは簡単です。コアデータからすべての本をクエリして表示するだけです。

サーバーはステートレスであり、ユーザーが本をダウンロードしたかどうかはわかりません。

ダウンロードした本をコアデータに保存しています。FetchedResultsControllerを使用してテーブルビューをダウンロードします。

ユーザーがカテゴリで検索/閲覧する場合は、新しいRESTリクエストを開始し、応答したJSONをメモリNSArrayのように使用してテーブルビューをバックアップし、タイトルや作成者名などを表示します。

書籍リストは大きく、サーバーは頭字語の使用や人気順に並べ替えるなどの高度な検索をサポートしています。したがって、リスト全体をダウンロードしてローカルで検索を実行するには、さらに作業が必要です。

書籍が検索ビューでダウンロードされているかどうかを判断するための更新の良い方法は何でしょうか。cellForRowAtIndexPathメインスレッドで毎回コアデータベースをクエリするのはコストがかかるようです。また、バックグラウンドダウンロードが終了したときにUIステータスをリアルタイムで更新したいので、ダウンロード後にJSONを変更することもできませんでした

ありがとう

4

2 に答える 2

1

書籍のリストが小さい (一度にサーバーからダウンロードできるほど小さい) 場合は、そのモデルをメモリ内に構築することで問題を解決できる可能性があります。サーバーにクエリを実行し、CoreData の結果を使用して応答を修正し (すべてバックグラウンドで)、それUITableView自体を (UI スレッドで) リロードするように指示します。

説明する疑似コード:

dispatch_async(..., ^{
  [server requestData:param onComplete:^(NSDictionary* result){
    NSArray* someResult = [moc executeFetchRequest:...];
    NSArray* tableViewData = [mybusinesslogic mergeServerResult:result 
                              withCoreDataResult:someResult];
    myTableViewController.tableViewData = tableViewData;
    dispatch_async(dispatch_get_main_queue(), ^{
      [myTableViewController.tableView reloadData];
    });
  }];
});
于 2013-02-04T01:51:36.343 に答える
0

各セルに対してコア データ クエリを実行すると、コストがかかります。したがって、単一のクエリを実行してから、メモリ内で一致させるだけです。本に、簡単に照合できる ID がある場合。おそらく次のようなものです:

1) 応答された JSON NSArray を取得します。(たぶん、ID を別の NSArray に解析します) 2) 1 つのクエリで、その中の ID を Core Data の ID に一致させます。次のように、一致する ID だけを含む配列を返します。

-(NSArray*) findMatchInGraph:(NSManagedObjectContext*)context forResults:(NSArray*)searchResultIDs {

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity: [NSEntityDescription entityForName:@"Books" inManagedObjectContext:context]];

    NSPredicate *reqPredicate = [NSPredicate predicateWithFormat:@"(id IN %@)", searchResults;
    [request setPredicate:reqPredicate];

    NSError *error = nil;
    NSArray *results = [context executeFetchRequest:request error:&error];
    NSMutableArray *matching = [NSMutableArray array];
    if (results) {
        for (NSManagedObject *item in results) {
            [matching addObject:[item valueForKey:@"id"]];
        }
    }
    return [matching copy];
}

3) TableViewController、一致する ID を持つインデックスのセルは、「ダウンロード済み」インジケーターを追加しますか?

これを行うには、もっと効率的な方法があるかもしれません。

于 2013-02-04T14:52:01.340 に答える