8

外部データ ソースを使用する iPhone 用の Core Data アプリケーションを作成しようとしています。オブジェクトを永続化するために Core Data を実際に使用しているのではなく、オブジェクトのライフサイクル管理のために使用しています。Core Data をローカル データに使用する方法についてはかなり良いアイデアがありますが、リモート データでいくつかの問題に遭遇しました。例として Flickr の API を使用します。

まず、最近の写真のリストが必要な場合は、外部データ ソースから写真を取得する必要があります。リストを取得したら、写真ごとに反復して管理対象オブジェクトを作成する必要があるようです。この時点で、コードを続行し、標準の Core Data API を使用してフェッチ リクエストを設定し、犬などの写真のサブセットを取得できます。

しかし、続けてユーザーの写真のリストを取得したい場合はどうすればよいでしょうか。これら 2 つのデータ セットが交差する可能性があるため、既存のデータに対してフェッチ リクエストを実行し、既存のものを更新してから、新しいオブジェクトを挿入する必要がありますか?

--

古いパターンでは、これらのデータ セットごとに個別のデータ構造を用意し、それらに適切にアクセスするだけでした。recentPhotos セットと usersPhotos セット。しかし、Core Data の一般的なパターンは 1 つの管理対象オブジェクト コンテキストを使用するように思われるため、データをメインのデータ プールとマージする必要があるようです (私が間違っている可能性があります)。しかし、写真のリストを取得するだけでも、かなりのオーバーヘッドがかかるようです。セットごとに別の管理対象オブジェクト コンテキストを作成する必要がありますか? ここでも Core Data を使用する必要がありますか?

Core Data について私が魅力的だと思うのは、以前は (Web サービスの場合) 特定のデータを要求し、要求でフィルター処理するか、コードでフィルター処理して、使用するリストを生成していたことです。Core Data を使用すると、オブジェクトのリストを取得してプールに追加し (必要に応じて古いオブジェクトを更新)、それに対してクエリを実行できます。ただし、このアプローチでわかる 1 つの問題は、オブジェクトが外部から削除された場合、古いデータを保持しているため、それを知ることができないということです。

私はここで基地から離れていますか?リモート データとコア データを処理するために人々が従うパターンはありますか? :) 私は、彼らがそれをやったと言っている人々の投稿をいくつか見つけました。ありがとう。

4

3 に答える 3

3

2 つのことを組み合わせてみてください。この戦略は、NSFetchRequest の結果を 2 回取得するインターフェイスを提供します。1 回目は同期的に、もう 1 回はデータがネットワークからロードされたときです。

  1. NSFetchRequestフェッチが終了したときに実行する追加のブロック プロパティを受け取る独自のサブクラスを作成します 。これは、ネットワークへの非同期リクエスト用です。呼びましょうFLRFetchRequest

  2. このリクエストを渡すクラスを作成します。と呼びましょう FLRPhotoManager。andのインスタンスを取るFLRPhotoManagerメソッドがあります...executeFetchRequest:FLRFetchRequest

    1. フェッチ リクエストに基づいてネットワーク リクエストをキューに入れ、保持されたフェッチ リクエストを渡して、ネットワーク リクエストが終了したときに再度処理します。
    2. CoreData キャッシュに対してフェッチ リクエストを実行し、すぐに結果を返します。
    3. ネットワーク リクエストが終了したら、コア データ キャッシュをネットワーク データで更新し、キャッシュに対してフェッチ リクエストを再度実行します。今度は、FLRFetchRequest からブロックをプルし、このフェッチ リクエストの結果をブロックに渡します。第二段階。

これは私が思いついた最良のパターンですが、あなたと同じように、他の人の意見に興味があります.

于 2010-09-23T01:50:38.477 に答える
2

あなたの最初の直感は正しいように思えます: fetchrequests を使用して既存のストアを更新する必要があります。私がインポーターに使用したアプローチは次のとおりです。インポートに適したすべてのファイルのリストを取得し、それをどこかに保存します。ここでは、そのリストの取得は高速で軽量 (名前と URL または一意の ID のみ) であると想定していますが、実際に何かをインポートするにはもう少し時間と労力がかかり、ユーザーはプログラムを終了するか、何かをしたくなる可能性があります。 else すべてのインポートが完了する前に。

次に、別のバックグラウンド スレッドで (これは NSRunLoop と NSTimer のおかげで思ったほど難しくありません。「Core Data: Efficiently Importing Data」でググってください)、そのリストの最初の項目を取得し、Flickr などからオブジェクトを取得し、それを Core Data データベースで検索します (効率的でキャッシュされた NSFetchRequests のセットアップに関する Apple の Predicate Programming Guide を注意深く読んでください)。リモート オブジェクトが既に Core Data に存在する場合は、必要に応じて情報を更新します。挿入されていない場合は、情報を更新します。それが完了したら、アイテムをインポートするリストから削除し、次のリストに進みます。

リモート ストアで削除されたオブジェクトの問題については、2 つの解決策があります。定期的な同期と遅延したオンデマンドの同期です。Flickr から写真をインポートすることは、元のものとそのすべてのメタデータをインポートすることを意味しますか (所有権などに関するポリシーが何であるかはわかりません)、それともサムネイルといくつかの情報をインポートしたいだけですか? すべてをローカルに保存する場合は、数日または数週間ごとにチェックを実行して、ローカル ストアのすべてがリモートでも存在するかどうかを確認できます。存在しない場合、ユーザーは写真を保持するか削除するかを決定できます。サムネイルまたはプレビューのみを保存する場合は、ユーザーが全体像を見たいと思うたびに Flickr に接続する必要があります。削除されている場合は、ユーザーに通知してローカルでも削除するか、アクセス不可としてマークすることができます。

于 2009-11-21T13:20:40.017 に答える
0

このような状況では、Cocoa のアーカイブ機能を使用して、写真オブジェクト (およびインデックス) をセッション間でディスクに保存し、アプリが Flickr を呼び出すたびにすべて上書きすることができます。

しかし、既に Core Data を使用しており、それが提供する機能が気に入っているので、データ モデルを変更して「source」または「callType」属性を含めてみませんか? 現時点では、ソース「Flickr API」を使用して一連のオブジェクトを暗黙的に作成していますが、さまざまな API 呼び出しを一意のソースとして簡単に処理し、それを明示的に保存できます。

削除を処理する最も簡単な方法は、更新されるたびにデータ ストアをクリアすることです。そうしないと、すべてを繰り返し処理し、新しい結果に含まれていないファイル名を持つ写真オブジェクトのみを削除する必要があります。

似たようなことを自分でやろうと思っているので参考になれば幸いです。

PS: セッション間で写真オブジェクトをまったく保存しない場合は、2 つの異なるコンテキストを使用して、それらを個別にクエリすることができます。それらが保存されておらず、中央ストアにまだ何も入っていない限り、あなたが説明したように機能します.

于 2009-11-10T04:17:31.067 に答える