请指导我以下问题。
我有两个关系实体,如下图所示
我正在使用最新版本的RestKit和iOS 7
现在在我的appDelegate中,我正在使用“List”实体的以下映射
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];
并为我的Task对象使用以下映射
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]];
应用程序因此错误而崩溃实体列表不符合密钥值,符合密钥“list”。
如果我省略上面的代码并尝试从关系中获取listID
task.list.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模型有一个关系“tasks”所以我编辑我的休息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]];
希望这有助于为像我这样的人掌握关系概念。
答案 0 :(得分:5)
您的模态图显示您具有一对多关系(一个列表包含许多任务)。
据我所知,在这种情况下,您只需要在列表实体上添加关系映射,不需要任务实体。此外,对于一对多关系,您无需在list
实体下添加Task
关系。
您的实体关系应如下所示
请尝试按照
[listEntityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"YOUR_JSON_KEYPATH_HERE" toKeyPath:@"tasks" withMapping: taskEntityMapping]];
重要
以上方法
FromKeyPath parameter
应该是关系开始的JSON key
的名称。
toKeyPath parameter
应该是您在实体图中提到的relationship name
。即; tasks
。
withMapping
应该是许多实体的映射。在您的情况下taskEntityMapping
希望这可以解决问题。
答案 1 :(得分:0)
不确定为什么这不起作用,但您可以尝试创建这样的关系映射:
[taskEntityMapping addConnectionForRelationship:@"list" connectedBy:@{ @"listId": @"listId" }];
[listEntityMapping addConnectionForRelationship:@"tasks" connectedBy:@{ @"listId":@"listId"}];