請指導我關於以下問題。RestKit添加屬性映射和關係映射
我有兩個實體的關係如圖下圖
我使用最新版本的RestKit的與iOS 7
現在在我的appDelegate我使用下面的映射「列表」實體
NSDictionary *listObjectMapping = @{
@"listID" : @"listID",
@"listName" : @"listName",
@"listSyncStatus" : @"listSyncStatus"
};
RKEntityMapping *listEntityMapping = [RKEntityMapping mappingForEntityForName:@"List" inManagedObjectStore:managedObjectStore];
[listEntityMapping addAttributeMappingsFromDictionary:listObjectMapping];
listEntityMapping.identificationAttributes = @[ @"listID" ];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:listEntityMapping
method:RKRequestMethodGET
pathPattern:@"/api/lists"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor];
//Inverse mapping, to perform a POST
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[listEntityMapping inverseMapping]
objectClass:[List class]
rootKeyPath:nil
method:RKRequestMethodPOST];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[objectManager setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"application/json"];
[objectManager addRequestDescriptor:requestDescriptor];
//Inverse mapping, to perform a PUT
requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[listEntityMapping inverseMapping]
objectClass:[List class]
rootKeyPath:nil
method:RKRequestMethodPUT];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[objectManager setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"application/json"];
[objectManager addRequestDescriptor:requestDescriptor];
,並使用下面的映射爲我的任務對象
NSDictionary *taskObjectMapping = @{
@"listID" : @"listID",
@"taskID" : @"taskID",
@"taskName" : @"taskName",
@"taskCompletionStatus" : @"taskCompletionStatus",
@"taskSyncStatus" : @"taskSyncStatus"
};
RKEntityMapping *taskEntityMapping = [RKEntityMapping mappingForEntityForName:@"Task" inManagedObjectStore:managedObjectStore];
[taskEntityMapping addAttributeMappingsFromDictionary:taskObjectMapping];
taskEntityMapping.identificationAttributes = @[ @"taskID" ];
RKResponseDescriptor *taskResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:taskEntityMapping
method:RKRequestMethodGET
pathPattern:@"/api/list/:id"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:taskResponseDescriptor];
//Inverse mapping, to perform a POST
RKRequestDescriptor *taskRequestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[taskEntityMapping inverseMapping]
objectClass:[Task class]
rootKeyPath:nil
method:RKRequestMethodPOST];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[objectManager setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"application/json"];
[objectManager addRequestDescriptor:taskRequestDescriptor];
//Inverse mapping, to perform a PUT
taskRequestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[taskEntityMapping inverseMapping]
objectClass:[Task class]
rootKeyPath:nil
method:RKRequestMethodPUT];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[objectManager setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"application/json"];
[objectManager addRequestDescriptor:taskRequestDescriptor];
現在我的問題是如何在這兩個實體之間添加關係映射? 什麼是正確的方法?
如果我使用我使用的代碼
[taskEntityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"list.listID"
toKeyPath:@"listID"
withMapping:listEntityMapping]];
一個運行時錯誤時說:「無法添加映射的keyPath listID,已經存在一個」
,如果我用這個
以下行[listEntityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"listID"
toKeyPath:@"list.listID"
withMapping:taskEntityMapping]];
應用程序與此錯誤崩潰實體列表不是關鍵值編碼兼容t他關鍵的「名單」。
,如果我省略上面的代碼,並嘗試從關係
task.list.listID
得到listID它給了我「0」。任何人都可以告訴我到底我做錯了什麼,或者我應該怎麼做才能完成上述任務。如果需要,我可以提供更多細節。
編輯
,但我請求所有列表返回以下JSON
GET www.mydomain.com/api/lists
[
{"listID":"42","listName":"List 4","listSyncStatus":"1"},
{"listID":"41","listName":"List 3","listSyncStatus":"1"},
{"listID":"40","listName":"List 2","listSyncStatus":"1"}
]
,並要求單獨的列表如下
GET www.mydomain.com/api/list/42
[
{"taskID":"22","listID":"42","taskName":"Task 2","taskSyncStatus":"1","taskCompletionStatus":"1"},
{"taskID":"21","listID":"42","taskName":"Task 1","taskSyncStatus":"1","taskCompletionStatus":"1"}
]
即會返回其任務是沒有級聯關係在json中返回。這是錯誤的方式還是我在這裏失蹤?
更正接受答案
後,事實證明我是錯了返回JSON即返回的JSON中沒有任何關係,而iOS的模式有關係「任務」,所以我編輯我的REST API返回正確的嵌套JSON是像下面
[ { "listID" : "96",
"listName" : "List 1",
"listSyncStatus" : "1",
"tasks" : [ { "taskCompletionStatus" : "1",
"taskID" : "67",
"taskName" : "Task 2",
"taskSyncStatus" : "1"
},
{ "taskCompletionStatus" : "1",
"taskID" : "66",
"taskName" : "Task 1",
"taskSyncStatus" : "1"
}
]
},
{ "listID" : "97",
"listName" : "List 2",
"listSyncStatus" : "1",
"tasks" : [ { "taskCompletionStatus" : "1",
"taskID" : "69",
"taskName" : "Task 1",
"taskSyncStatus" : "1"
},
{ "taskCompletionStatus" : "1",
"taskID" : "68",
"taskName" : "Task 1",
"taskSyncStatus" : "1"
}
]
}
]
以上的嵌套JSON回來後,一切正常般的魅力,特別是這條線
[listEntityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"tasks"
toKeyPath:@"tasks"
withMapping:taskEntityMapping]];
希望這有助於把握像我這樣的人的關係概念。
iOS建議應該存在反向關係。 – Umair
@Umair,謝謝你是對的:)。消除反向關係的建議是爲了讓你的代碼儘可能少。所以調試可以很容易。如果事情現在正在運行良好,您可以根據需要添加反比關係。這是我喜歡如何調試我的代碼:) – Khawar
@Khawar很多感謝您的解釋 – gbk