読者です 読者をやめる 読者になる 読者になる

49hack

見習いエンジニアが魔法使いになるまで

レスポンスにリレーションがない場合にCoreDataからも削除する

restkit objective-c

たとえば、次のようにcommunitytopicにリレーションがあり、

RKEntityMapping *communityMapping = [RKEntityMapping mappingForEntityForName:@"HogeCommunity"
                                                        inManagedObjectStore:managedObjectStore];
[communityMapping addAttributeMappingsFromDictionary:@{
                                                       @"id":               @"communityId",
                                                       @"title":            @"title",
                                                       }];

communityMapping.identificationAttributes = @[ @"communityId" ];

RKEntityMapping *topicMapping = [RKEntityMapping mappingForEntityForName:@"HogeTopic"
                                                    inManagedObjectStore:managedObjectStore];
[topicMapping addAttributeMappingsFromDictionary:@{
                                                   @"id":                   @"topicId",
                                                   @"message":              @"message",
                                                   }];
topicMapping.identificationAttributes = @[ @"topicId" ];

[communityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"topic" toKeyPath:@"topic" withMapping:topicMapping]];

APIを叩いたときのレスポンスは次のような感じだとします。

community : { id : 1,
              title : "ほげほげ",
              topic : {id : 1, message : "あいう"}
            },
...

サーバーのDBからtopicを削除し、レスポンスが以下のようになったとします。

community : { id : 1,
              title : "ほげほげ",
            },
...

この場合、端末側ではtopicが削除されたことを検知していないため、リレーションが残ったままです。

NSLog(@"id : %@", community.topic.topicId);       // 1
NSLog(@"message : %@", community.topic.message);  // あいう

これを防ぐためには、レスポンスにリレーションがなかった場合にCoreDataから削除するオプションを追加してあげればOKです。

// レスポンスにリレーションがない場合はCoreDataから削除してください的なオプション
communityMapping.setNilForMissingRelationships = YES;

こういうオプションあるはずですよね。知らなくて結構苦労しました。。

参考