4

私はしばらくの間RESTKitを使用していて、jsonをロードしてデータベースに保存する方が簡単です。しかし、私は時々グーグルをしていて、この問題の解決策を見つけることができませんでした。

私は、3つの異なるエンティティが互いにまっすぐな1対1の関係を持つように管理オブジェクトモデルを設定しています。私のモデルのレイアウトは次のとおりです。

ここに画像の説明を入力してください

オブジェクトをFriendクラスにロードすると、Friendモデルのマッピング関係に基づいて、残りの2つのモデルにもマッピングされます。

ユーザーが自分のFacebookアカウントに接続し、アカウントにリンクされているとすると、jsonの応答にLinkedInとFriendモデルのマッピングが含まれることは明らかです。このような場合のjsonの応答は次のようになります。

[
   {
      "name":"foo bar",
      "id":307,
      "facebook":{
         "name":"foo bar",
         "username":"foo.bar.5074",
         "id":"1000013421379389",
         "picture":"https://fbcdn-profile-a.akamaihd.net/foo-bar.jpg"
      },
     "linkedin":{
         "name":"foo bar",
         "headline":"some headline",
         "id":"1000013",
         "link":"http://www.linkedin.com/foo.bar",
         "image":"https://linkedin.com/foo-bar.jpg"
      },
      "picture":"https://fbcdn-profile-a.akamaihd.net/foo-bar.jpg"
   },
   {
     ... 
    }
  ]

ただし、ユーザーがFacebookとLinkedinをリンクすると、Webサイトからリンクを解除することもできます。したがって、ユーザーがリンクを解除すると、json応答は通常と同じマッピングを持たず、応答が次のようになるように、json応答にfacebookオブジェクトまたはlinkedinオブジェクトが含まれない可能性があります。

[
       {
          "name":"foo bar",
          "id":307,
          "facebook":{
             "name":"foo bar",
             "username":"foo.bar.5074",
             "id":"1000013421379389",
             "picture":"https://fbcdn-profile-a.akamaihd.net/foo-bar.jpg"
          },
          "picture":"https://fbcdn-profile-a.akamaihd.net/foo-bar.jpg"
       },
       {
         ... 
        }
      ]

そのような応答があった場合、ユーザーの既存のリンクされたレコードを削除したいと思います。または、応答にfacebookがない場合、またはその両方がない場合は、ローカルレコードとモデルの関連付けのいずれかが応答で空になっている方を削除したい場合があります。

RESTKitで関連するオブジェクトを自動的に削除したいと思います。オブジェクトローダーでフェッチリクエストを指定することでRestkitを介して可能だと思いますが、特によくわかりません。オブジェクトをロードするためにこのようにローダーパターンを使用しているので、フェッチ要求をどこに指定しますか?

編集済み

RKObjectMappingProvider *provider = [RKObjectMappingProvider mappingProvider];
[provider setObjectMapping:[self objectMappingForFriend] forKeyPath:@""];

[provider setObjectMapping:[self objectMappingForFriend] forResourcePathPattern:resourcePath withFetchRequestBlock:^NSFetchRequest *(NSString *resourcePath) {

    return [Friend fetchRequest];

}];

    [[[RKObjectManager sharedManager] loadObjectsAtResourcePath:resourcePath usingBlock:^(RKObjectLoader *loader){
        loader.mappingProvider = provider;
        loader.delegate = self;
        loader.method = RKRequestMethodGET;
    }];

_ここに冗長なコードがあると思います。_

これで、応答が空のときにローカルストア内のすべてのオブジェクトを削除したいと思いました。しかし、それは私にはうまくいきません。この問題をどのように回避すべきかわかりません。

更新:2012年7月8日午後2時23分現地時間

self.objectManager = [RKObjectManager objectManagerWithBaseURL:[NSURL URLWithString: @"https://mywebsite"]];
        self.objectManager.client.disableCertificateValidation = YES;
        self.objectManager.client.cachePolicy = RKRequestCachePolicyLoadIfOffline | RKRequestCachePolicyLoadOnError | RKRequestCachePolicyTimeout | RKRequestCachePolicyEtag;
        self.objectManager.requestCache.storagePolicy = RKRequestCacheStoragePolicyPermanently;
        self.objectManager.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
        self.objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"test.sqlite" ];
        self.objectManager.objectStore.cacheStrategy = [RKInMemoryManagedObjectCache new];

次に、マッピング広告の読み込みデータを設定します。

RKObjectMappingProvider *provider = [RKObjectMappingProvider mappingProvider];
[provider setObjectMapping:[self objectMappingForFriend] forKeyPath:@""];

[provider setObjectMapping:[self objectMappingForFriend] forResourcePathPattern:resourcePath withFetchRequestBlock:^NSFetchRequest *(NSString *resourcePath) {

    return [Friend fetchRequest];

}];

    [[[RKObjectManager sharedManager] loadObjectsAtResourcePath:resourcePath usingBlock:^(RKObjectLoader *loader){
        loader.mappingProvider = provider;
        loader.delegate = self;
        loader.method = RKRequestMethodGET;
    }];

更新:2012年7月8日午後4時11分現地時間

一部のローカルオブジェクトを無効にしているようですが、オブジェクトの一部のみが参照を持っており、空のjson応答がある場合でも、メインモデルのFriendはまだ存在しています。

4

4 に答える 4

4

ここで構成する設定は2つあります。まず、RKObjectMappingで、setNilForMissingRelationshipsをYESに設定します。次に、Core Dataリレーションシップに正しい削除ルールがあることも確認する必要があります(リレーションシップを編集するときの[ユーティリティ]パネルで)。各削除ルールの機能の説明については、これを参照してください。

于 2012-07-18T06:42:02.230 に答える
2

RestKitの最新バージョンを使用していると想定する必要があります。だから、この行を試してみてください:

[RKObjectManager sharedManager].objectStore.managedObjectCache = [RKFetchRequestManagedObjectCache new];

GETリクエストが成功すると、最終的に[RKManagedObjectLoader deleteCachedObjectsMissingFromResult:]が呼び出され、ローカルデータがアンキャッシュされます。原則は、前の質問に対する以前の回答でリンクした記事でよりよく説明されています。

于 2012-07-18T09:45:04.273 に答える
2

キャッシュ戦略の設定方法は次のとおりです

[RKObjectManager sharedManager].objectStore.cacheStrategy = [RKFetchRequestManagedObjectCache new];
于 2012-11-08T22:13:09.210 に答える
1

新しいRestKitでは、fetchRequestブロックを次のように使用してこれを行うことができます。

 [[RKObjectManager sharedManager] addFetchRequestBlock:[self fetchRequestBlock]];


-(RKFetchRequestBlock)fetchRequestBlock{
  RKFetchRequestBlock fetchRequestBlock = ^NSFetchRequest*(NSURL *url){
    if( [url.relativePath isEqualToString:@"api/app/v1/network_contacts"] ){
      return [NSFetchRequest fetchRequestWithEntityName:@"Person"] ;
    }
    return nil ;
  };
  return fetchRequestBlock;
}

このメソッドは、ローカルデータベースにクエリを実行してリモートオブジェクトを比較し、一致しない場合はローカルストアからオブジェクトを削除します。

于 2014-03-13T23:10:59.417 に答える