使用RestKIt映射核心数据实体中的json对象

时间:2014-02-03 08:28:17

标签: ios json core-data restkit restkit-0.20

我正在使用RestKit开发一些待办事项列表应用程序。关于iOS中返回的带有CoreData的json表单服务器,我遇到了一些映射问题。

情景

以下是我正在使用的列表和任务实体的图像。

enter image description here

当有人向服务器上的列表添加新任务时,我将返回该特定列表的Json:

`GET www.mydomain.com\api\list\1`

        [ { "list" : 

          { "listID" : "1",
            "listName" : "New List ",
            "listSyncStatus" : "1"
          },
        "tasks" : [ { "listID" : "1",
              "taskCompletionStatus" : "1",
              "taskID" : "24",
              "taskName" : "Server Added 2",
              "taskSyncStatus" : "1"
            },
            { "listID" : "1",
              "taskCompletionStatus" : "1",
              "taskID" : "25",
              "taskName" : "Server Added 3",
              "taskSyncStatus" : "1"
            },
            { "listID" : "1",
              "taskCompletionStatus" : "1",
              "taskID" : "23",
              "taskName" : "Server Added",
              "taskSyncStatus" : "1"
            }
          ]
      } 
    ]

上面json的响应描述符如下:

    RKResponseDescriptor *taskResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:taskEntityMapping
                                                                                            method:RKRequestMethodGET
                                                                                       pathPattern:@"/api/list/:id"
                                                                                           keyPath:@"tasks"
                                                                                       statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

对于我的核心数据映射,我使用以下关系映射:

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

我的taskEntityMapping如下:

    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" ];

我的listEntityMapping如下:

    //ALL LISTS RELATED REQUESTS
NSDictionary *listObjectMapping = @{
                                      @"listID" : @"listID",
                                      @"listName" : @"listName",
                                      @"listSyncStatus" : @"listSyncStatus",

                                  };

RKEntityMapping *listEntityMapping = [RKEntityMapping mappingForEntityForName:@"List" inManagedObjectStore:managedObjectStore];
[listEntityMapping addAttributeMappingsFromDictionary:listObjectMapping];

listEntityMapping.identificationAttributes = @[ @"listID" ];

执行时,我的应用程序崩溃并出现以下错误 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Expected a dictionary representation'

和请求日志如下:

2014-02-03 13:17:29.789 RKGist[984:70b] T restkit.network:RKObjectRequestOperation.m:178 GET 'http://mydomain.com/api/list/1':
request.headers={
    Accept = "application/json";
    "Accept-Language" = "en;q=1, fr;q=0.9, de;q=0.8, zh-Hans;q=0.7, zh-Hant;q=0.6, ja;q=0.5";
    "User-Agent" = "RKGist/1.0 (iPhone Simulator; iOS 7.0.3; Scale/2.00)";
}
request.body=(null)
2014-02-03 13:17:30.670 RKGist[984:f03] T restkit.network:RKResponseMapperOperation.m:451 Mapping HTTP response to nil target object...
2014-02-03 13:17:30.670 RKGist[984:f03] D restkit.object_mapping:RKMapperOperation.m:377 Executing mapping operation for representation: (
        {
        list =         {
            listID = 1;
            listName = "New List ";
            listSyncStatus = 1;
        };
        tasks =         (
                        {
                listID = 1;
                taskCompletionStatus = 1;
                taskID = 24;
                taskName = "Server Added 2";
                taskSyncStatus = 1;
            },
                        {
                listID = 1;
                taskCompletionStatus = 1;
                taskID = 25;
                taskName = "Server Added 3";
                taskSyncStatus = 1;
            },
                        {
                listID = 1;
                taskCompletionStatus = 1;
                taskID = 23;
                taskName = "Server Added";
                taskSyncStatus = 1;
            }
        );
    }
)
 and targetObject: (null)
2014-02-03 13:17:30.671 RKGist[984:f03] T restkit.object_mapping:RKMapperOperation.m:320 Examining keyPath 'tasks' for mappable content...
2014-02-03 13:17:30.671 RKGist[984:f03] D restkit.object_mapping:RKMapperOperation.m:297 Found mappable collection at keyPath 'tasks': (
        (
                {
            listID = 1;
            taskCompletionStatus = 1;
            taskID = 24;
            taskName = "Server Added 2";
            taskSyncStatus = 1;
        },
                {
            listID = 1;
            taskCompletionStatus = 1;
            taskID = 25;
            taskName = "Server Added 3";
            taskSyncStatus = 1;
        },
                {
            listID = 1;
            taskCompletionStatus = 1;
            taskID = 23;
            taskName = "Server Added";
            taskSyncStatus = 1;
        }
    )
)

日志说在密钥路径tasks找到了mappable集合。

任何人都可以指导我在这里做错了什么。我的返回json格式是错误的还是我的映射代码错了?

1 个答案:

答案 0 :(得分:1)

您的响应描述符使用keyPath:@"tasks"。这有效地“挖掘”了响应并忽略了tasks部分之外的任何内容。这意味着在映射期间,您无法访问list部分。

使用addPropertyMapping:与关系是嵌套映射 - 这不是你拥有的。实际上,您需要单独映射2个单独的部分(因此,2个响应描述符),以创建具有关联ID(以及连接对象的ID)的所有对象。然后,您需要使用外键映射来建立连接(使用RKConnectionDescription)。

要检查的是JSON返回的内容。看起来好像它可能是一个包含一个对象的大数组而且没有意义。如果它是一个数组,那么你需要改变你的整个方法。它应该是一个带有多个键的对象......