1. ホーム
  2. iphone

[解決済み] CoreDataとREST Webサービスを非同期で同期し、同時にRESTエラーをUIに正しく反映させる方法

2023-06-25 17:58:48

質問

アプリのモデル層を作っているところです。

いくつかの要件はこんな感じです。

  1. iPhone OS 3.0 以上で動作すること。
  2. データのソースはRESTfulなRailsアプリケーションです。
  3. Core Dataを使用してデータをローカルにキャッシュする必要があります。
  4. クライアントコード(UIコントローラ)は、ネットワークに関する知識をできるだけ持たず、Core Data APIを使ってモデルの問い合わせや更新を行うようにします。

をチェックアウトしました。 WWDC10 セッション 117 オブジェクト リソース , コア・リソース そして RestfulCoreData フレームワークがあります。

Objective Resourceフレームワークは、それ自体ではCore Dataと会話せず、単なるRESTクライアントの実装に過ぎません。Core ResourceとRestfulCoreDataはすべて、あなたのコードでCore Dataと話すことを想定しており、モデル層のバックグラウンドですべてのナットアンドボルトを解決してくれます。

ここまでは問題なく、当初はCore ResourceかRestfulCoreDataのどちらかが上記の要件をすべてカバーすると考えていましたが、... しかし......どれも正しく解決できそうにないことがいくつかあります。

  1. サーバーにローカル更新を保存している間、メイン スレッドはブロックされるべきではない。
  2. 保存操作が失敗した場合、UIにエラーが伝わり、ローカルのCore Dataストレージに変更が保存されないようにしなければなりません。

を呼び出すと、Core Resourceはサーバーにすべてのリクエストを発行します。 - (BOOL)save:(NSError **)error を呼び出したとき、Core Resource はサーバーへのすべての要求を発行します。したがって、サーバーへの根本的な要求が何らかの形で失敗した場合、正しい NSError インスタンスを提供することが可能です。しかし、保存操作が終了するまで呼び出し側のスレッドをブロックしてしまいます。FAILです。

RestfulCoreDataはあなたの -save: の呼び出しはそのまま維持され、クライアントのスレッドに追加の待ち時間を発生させません。それは単に NSManagedObjectContextDidSaveNotification を監視し、通知ハンドラでサーバーに対応するリクエストを発行するだけです。しかし、この方法では -save: の呼び出しは常に正常に完了し (まあ、Core Data が保存された変更に問題ないなら)、 実際に呼び出したクライアントコードは、保存がサーバーに伝わらなかったことを知る術がありません。 404 または 421 といったサーバー側のエラーが発生します。そしてさらに、ローカルストレージはデータが更新されるようになりますが、サーバーはその変更について知ることはありません。FAILです。

そこで、私はこれらすべての問題に対処するための可能な解決策/一般的な実践方法を探しています。

  1. 呼び出し側のスレッドが、それぞれの -save: を呼び出すスレッドがブロックされないようにします。
  2. 何らかの同期操作に失敗したことをUIで何とか通知してほしい。
  3. サーバーへのリクエストに失敗した場合、実際のCore Dataの保存も失敗させたい。

何かアイデアはありますか?

どのように解決するのですか?

あなたは本当にRestKitを見てみましょう( http://restkit.org ) を見てみるべきです。これは、リモートJSONリソースをモデル化し、ローカルのCore Dataにバックアップされたキャッシュに同期する問題を解決するために設計されています。ネットワークが利用できないときに、キャッシュから完全に作業するためのオフラインモードをサポートしています。すべての同期はバックグラウンドスレッドで行われ(ネットワークアクセス、ペイロードパーシング、マネージドオブジェクトコンテキストマージ)、デリゲートメソッドの豊富なセットがあるので、何が起こっているのかを知ることができます。