如何使用RestKit 0.2和Core Data在未嵌入的JSON对象和关系之间添加映射?

时间:2013-07-01 16:58:06

标签: ios json cocoa-touch core-data restkit

我正在开发我的第一个使用RestKit 0.2和Core Data的iOS应用程序。大部分时间我都遵循这个伟大的教程http://www.alexedge.co.uk/blog/2013/03/08/introduction-restkit-0-20/ 但它不符合我的要求,因为它描述了嵌入式JSON对象,我需要创建单独的对象。以下是我的应用结构的简化方案:

JSON响应:

"application": [
    {
        "appId": "148",
        "appName": …
.
.
.
(more attributes)
    }
],
"image": [
    {
        "imgId": "308",
        "appId": "148",
        "iType": "screenshot",
        "iPath": ..
.
.
.
    },
    {
        "imgId": "307",
        "appId": "148",
        "iType": "logo",
        "iPath": …
.
.
.
    }
]

我创建了一个包含两个实体的数据模型,并以一个应用程序可能有多个图像而一个图像只能属于一个应用程序的方式设置它们之间的关系:

enter image description here

我使用了mogenerator来创建实体代表的类。

我可以使用以下代码成功将实体映射到Application对象:

NSDictionary *parentObjectMapping = @{
                                      @"appId" : @"appId"
                                      };


// Map the Application object
RKEntityMapping *applicationMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Application class]) inManagedObjectStore:managedObjectStore];
applicationMapping.identificationAttributes = @[ @"appId" ];
[applicationMapping addAttributeMappingsFromDictionary:@{
 @"appName" : @"name",
 @"appCat" : @"category",
 @"appType" : @"type",
 @"compName" : @"companyName",
 @"compWeb" : @"companyWebsite",
 @"dLink" : @"downloadWebLink",
 @"packageName" : @"appStoreLink",
 @"osMinVer" : @"minRequirements",
 @"appCost" : @"cost",
 @"appDescription" : @"appDescription"
 }];

[applicationMapping addAttributeMappingsFromDictionary:parentObjectMapping];

 // Register our mappings with the provider
 [manager addResponseDescriptorsFromArray:@[

 [RKResponseDescriptor responseDescriptorWithMapping:applicationMapping
 pathPattern:nil
 keyPath:@"application"
 statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]
 ]];

现在,在使用Image和Application之间的适当关系将JSON映射到图像对象时,我遇到了问题。如何在两个实体之间添加映射?我的数据模型是正确的还是我遗漏了什么?

2 个答案:

答案 0 :(得分:5)

您希望使用外键映射来允许RestKit连接对象。

您需要添加图片映射,它应该有一个属性来保存appId。然后,您需要添加连接关系:

[imageMapping addConnectionForRelationship:@"application" connectedBy:@{ @"appId": @"appId" }];

告诉RestKit使用图像实例上的appId属性连接到具有相应appId的应用程序实例,并将结果保存为application关系。

答案 1 :(得分:1)

我假设您无法更改“image”JSON对象的数据结构,因此就自动关系映射而言,这将限制RestKit的功能。但是,您仍然可以自己建立关系。

首先,您需要在数据模型中添加一个字段appId

然后,设置图像映射,如下所示:

RKEntityMapping* imageMapping = [RKEntityMapping mappingForEntityForName:@"Image" inManagedObjectStore:objectManager.managedObjectStore];
[imageMapping addAttributeMappingsFromDictionary:@{
 @"imgId" : @"imageId",
 @"iPath" : @"clientPath",
 @"iType" : @"type",
 @"sPath" : @"serverPath",
 @"appId" : @"appId"
 }];
imageMapping.identificationAttributes = @[ @"imageId" ];
RKResponseDescriptor *imageResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:imageMapping pathPattern:nil keyPath:@"image" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:imageResponseDescriptor];

在此之后,您的映射应该完成。要使用您的对象填充本地数据库,请拨打此电话getObjectsAtPath

[[RKObjectManager sharedManager] getObjectsAtPath:@"/yourWebServiceURL" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
    // success block
    NSLog(@"Success!");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
    //fail block
}];

这应该将所有对象加载到CoreData中。在应用程序的另一个位置,甚至可能在上面调用的成功块中,您需要将Image对象连接到Application对象。您需要获取请求和for循环。只需将每个Image的“应用”属性指定为具有相同Application的{​​{1}}对象,如下所示:

appId

然后,您可以使用myImage.application = fetchedApplicationWithID; [myImage application]两种方式查找关系。