ios - RestKit 添加属性映射和关系映射

标签 ios objective-c restkit restkit-0.20

请指导我解决以下问题。

我有两个实体,它们之间的关系如下图所示 enter image description here

我在 iOS 7 上使用最新版本的 RestKit

现在在我的 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]];

应用因此错误而崩溃实体列表与键“列表”的键值编码不兼容。'

如果我省略上面的代码并尝试从关系中获取 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 模型有关系“任务”,所以我编辑了我的 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]];

希望这有助于像我这样的人掌握关系概念。

最佳答案

您的模态图显示您具有一对多 关系(一个列表有多个任务)。

据我所知,在这种情况下,您只需要在 List 实体上添加关系映射,而不需要在 Task 实体上添加关系映射。同样对于一对多关系,您不需要在Task实体下添加list关系。

你的实体关系应该是这样的

enter image description here

所以试试看

[listEntityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"YOUR_JSON_KEYPATH_HERE" toKeyPath:@"tasks" withMapping: taskEntityMapping]];

重要

在上面的方法中

FromKeyPath 参数 应该是关系开始处的 JSON 键 的名称。

toKeyPath 参数 应该是您在实体图中提到的关系名称。 IE; 任务

withMapping 应该是很多实体的映射。在你的情况下 taskEntityMapping

希望这能解决问题。

关于ios - RestKit 添加属性映射和关系映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21429811/

相关文章:

objective-c - UIScrollView 分页有 2 个 View

ios - UIBarButtonItem 的 TintColor 在 iPhone 5C 上错误地显示为灰色,但在 4S、6 和所有模拟器选项上正确显示为白色。为什么?

iOS:目前有没有办法防止两个 View Controller 同时被推送或弹出?

ios - 核心数据不一致 - 获取有时不返回任何内容

ios - RestKit: 'Unacceptable type of value for to-one relationship: property = " Prop ”;所需类型 = A 型;给定类型 = TypeS;

ios - 水平 UIButton 中的垂直文本

ios - 如何在基于页面的应用程序 (PageViewController) 中单击按钮从 ViewController1 移动到 ViewController2

ios - 测试两个整数以确定现在是白天还是晚上

ios - AVAudioPlayer.currentTime 在更改速率时给出错误的值

iOS RestKit人工识别属性