2012-06-09 13 views
5

私は、カスタムRESTFul APIとインターフェイスするアプリケーションを構築するために、iOS 5.0デプロイメントターゲットでCore Dataを持つRestKit 0.10.1を使用しています。オフライン接続が重要なので、デバイスのローカルCoreDataデータベースにユーザーのデータのキャッシュを保持しています。RestKit + CoreData:リモート保存が成功した後にオブジェクトをローカルに保存する方法はありますか?

RestKitはかなり素晴らしいですし、RKFetchResultsTableControllerをセットアップしてデータを簡単に表示して永続化させるのは簡単です。しかし、RestKitの動作は理想的ではなく、変更方法を理解できません。

「録音」というモデルがあります。新しい録音を作成するために、私は次のことをやっている:

Recording *r = [NSEntityDescription insertNewObjectForEntityForName:@"Recording" inManagedObjectContext:[[RKObjectManager sharedManager].objectStore managedObjectContextForCurrentThread]]; 

r.name = newName; 

[[RKObjectManager sharedManager] sendObject:r toResourcePath:@"/recordings" usingBlock:^(RKObjectLoader *loader){ 
     loader.delegate = self; 
     loader.method = RKRequestMethodPOST; 
     loader.serializationMIMEType = RKMIMETypeJSON; 

     loader.serializationMapping = [RKObjectMapping serializationMappingUsingBlock:^(RKObjectMapping *serializationMapping){ 
      [serializationMapping mapAttributes:@"name", nil]; 

     }]; 

     RBMappingProvider *mappings = (RBMappingProvider *)[[RKObjectManager sharedManager] mappingProvider]; 
     loader.objectMapping = [mappings recordingObjectMapping]; 

    }]; 

これは「録音」タイプの新しいエンティティを作成し、POSTリクエストでサーバにエンティティを送信します。成功した場合、これは素晴らしいです。

ただし、サーバーがこれらの作成を合法的に拒否することがあるという問題があります。このような状況で私が見つけたのは、コアデータデータベースにIDの0(IDはサーバーによって設定されたプライマリキー)のエンティティのローカルコピーが既に存在することです。

ローカルエンティティを削除する唯一の方法は、サーバーからローカルデータを強制的に更新することです。

サーバが2xxで応答した場合にのみオブジェクトをローカルに保持する方法はありますか?あるいは、サーバーが2xx以外の何かで応答した場合、変更を元に戻す方法はありますか?

おかげで、残念ながら

+0

FWIW、RestKitドキュメントに規定する 記録*をR = [録画オブジェクト] とエンティティを作成することで、すべての動作を変更しません。 – apurva

+0

RKにサーバレスポンスのコールバックメソッドがありませんか?オブジェクトへの参照を保持し、アップロードが拒否された場合は削除します。 – Mundi

+0

@mundiこれは1つのアプローチであり、より望ましいものでもあります。しかし、サーバがペイロードを受け入れた後でのみ、ローカル状態を維持することが可能かどうか疑問に思っていました。これにより、冗長コードが大幅に少なくなります。 – apurva

答えて

0

、録音はNSManagedObjectであるので、でもあなたの一時的なインスタンスは、管理対象オブジェクトコンテキストに挿入する必要があります。参照を維持し、エラーの後で文脈からそれを削除する@ムンディの解決策は、私が使用する解決策です。少し余分なコードがサーバーから完全にリフレッシュされます。

0.20.xにアップグレードすると、これは簡単になります。要求を送信する際に使用される成功と失敗のブロックは、この参照を保持し、失敗した場合にはそれを削除することを非常に容易にします。例えば:

[_objectManager postObject:aMessage 
         path:@"message" 
       parameters:parameters 
        success:^(RKObjectRequestOperation * operation, RKMappingResult * mappingResult){ 
        // Success code here 
        } 
        failure:^(RKObjectRequestOperation * operation, NSError * error){ 
        [_managedObjectContext deleteObject:aMessage]; 
        [_managedObjectContext save:nil]; 
        }]; 
関連する問題