RestKit到Core Data Mapping创建了Subentity的对象

时间:2014-07-13 17:37:50

标签: ios core-data mapping restkit

我正在使用RestKit将JSON响应映射到具有父/子实体的核心数据。收到Parent个对象的JSON有效负载时会出现问题,因为它们以某种方式映射到Child实体的实例(这真的很奇怪)。

让我们考虑以下映射(我注释掉了所有其他内容,甚至是子映射):

RKEntityMapping *parentMapping = [RKEntityMapping mappingForEntityForName:[Parent entityName] inManagedObjectStore:objectManager.managedObjectStore];
[parentMapping addAttributeMappingsFromDictionary:@{@"id": @"remoteObjectId"}];
[parentMapping addAttributeMappingsFromArray:@[ @"title" ]];
parentMapping.identificationAttributes = @[ @"remoteObjectId" ];
[objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:parentMapping method:RKRequestMethodAny pathPattern:@"Parents" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];

现在,当我启用Network和ObjectMapping跟踪日志记录时,会发生以下情况(请注意,在映射操作即将开始之前一切正常,但它突然成为Child个对象,而不是应该是Parent对象):

2014-07-13 18:19:15.311 uni-hd[26579:f03] T restkit.network:RKResponseMapperOperation.m:469 Mapping HTTP response to nil target object... // can you explain this as well?
2014-07-13 18:19:15.311 uni-hd[26579:f03] D restkit.object_mapping:RKMapperOperation.m:377 Executing mapping operation for representation: (
        {
        id = 1;
        title = Foo;
    },
        {
        id = 2;
        title = Bar;
    }
)
 and targetObject: (null)
2014-07-13 18:19:15.311 uni-hd[26579:f03] T restkit.object_mapping:RKMapperOperation.m:320 Examining keyPath '<null>' for mappable content...
2014-07-13 18:19:15.311 uni-hd[26579:f03] D restkit.object_mapping:RKMapperOperation.m:297 Found mappable collection at keyPath '<null>': (
        {
        id = 1;
        title = Foo;
    },
        {
        id = 2;
        title = Bar;
    }
)
2014-07-13 18:19:15.312 uni-hd[26579:f03] D restkit.object_mapping:RKMapperOperation.m:229 Asked to map source object {
    id = 1;
    title = Foo;
} with mapping <RKEntityMapping:0x10a615370 objectClass=**Parent** propertyMappings=(
    "<RKAttributeMapping: 0x10a616660 id => remoteObjectId>",
    "<RKAttributeMapping: 0x10a616370 title => title>"
)>
2014-07-13 18:19:15.312 uni-hd[26579:6703] D restkit.object_mapping:RKPropertyInspector.m:131 Cached property inspection for Class '**Parent**': {
    children =     {
        isPrimitive = 0;
        keyValueCodingClass = NSSet;
        name = children;
    };
    parent =     {
        isPrimitive = 0;
        keyValueCodingClass = Parent;
        name = parent;
    };
    remoteObjectId =     {
        isPrimitive = 1;
        keyValueCodingClass = NSNumber;
        name = remoteObjectId;
    };
    title =     {
        isPrimitive = 0;
        keyValueCodingClass = NSString;
        name = title;
    };
}
2014-07-13 18:19:15.312 uni-hd[26579:f03] D restkit.object_mapping:RKMappingOperation.m:859 Starting mapping operation...
// Why is it a Child object now?!
2014-07-13 18:19:15.313 uni-hd[26579:f03] T restkit.object_mapping:RKMappingOperation.m:860 Performing mapping operation: <RKMappingOperation 0x10a85d720> for '**Child**' object. Mapping values from object {
    id = 1;
    title = Foo;
} to object <**Child**: 0x10accc420> (entity: Child; id: 0xd00000000004000a <x-coredata://16E53A02-12F7-4A41-B0CB-8241A694F197/Child/p1> ; data: <fault>) with object mapping (null)
2014-07-13 18:19:15.313 uni-hd[26579:f03] T restkit.object_mapping:RKMappingOperation.m:438 Found transformable value at keyPath 'id'. Transforming from class '__NSCFNumber' to 'NSNumber'
2014-07-13 18:19:15.313 uni-hd[26579:f03] T restkit.object_mapping:RKMappingOperation.m:453 Mapping attribute value keyPath 'id' to 'remoteObjectId'
2014-07-13 18:19:15.314 uni-hd[26579:f03] T restkit.object_mapping:RKMappingOperation.m:484 Skipped mapping of attribute value from keyPath 'id to keyPath 'remoteObjectId' -- value is unchanged (1)
2014-07-13 18:19:15.314 uni-hd[26579:f03] T restkit.object_mapping:RKMappingOperation.m:438 Found transformable value at keyPath 'title'. Transforming from class '__NSCFString' to 'NSString'
2014-07-13 18:19:15.314 uni-hd[26579:f03] T restkit.object_mapping:RKMappingOperation.m:453 Mapping attribute value keyPath 'title' to 'title'
2014-07-13 18:19:15.315 uni-hd[26579:f03] T restkit.object_mapping:RKMappingOperation.m:469 Mapped attribute value from keyPath 'title' to 'title'. Value: Universität Heidelberg
2014-07-13 18:19:15.315 uni-hd[26579:f03] D restkit.object_mapping:RKMappingOperation.m:928 Finished mapping operation successfully...
(... second object mapping and end results ...)

因此,不是映射到Parent对象,而是创建Child对象。

在服务器上,这些是单独的模型,因此具有重叠的ID。这可能是(?)是相关的,尽管此时应该确实没有Child对象具有相同的id,因为数据库开始为空而可能会干扰。因为它显示Mapping [...] to object <**Child**: 0x10accc420>我怀疑在创建Child对象之前具有相同的remoteObjectId但是当我在JSON请求之前执行核心数据提取时,数据库为空。我发现this fixed issue on Github有关于连接描述的类似问题,但它没有提到对象的创建或标识/映射本身。

如何确保创建Parent个对象而不是其子实体Child的实例?

修改:我使用identificationPredicate找到了解决此问题的解决方案(请参阅下面的答案)。不过,这是我的模型:

Model

我记录了执行以下获取请求的商店内容:

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[UHDNewsCategory entityName]];
fetchRequest.includesSubentities = YES;

在JSON请求之前,商店中没有对象。之后,服务器响应中的每个UHDNewsSource(= Child)都有一个UHDNewsCategory(= Parent)对象。

1 个答案:

答案 0 :(得分:0)

我找到了解决此问题的方法,但它认为默认的RestKit实现并不像预期的那样工作。

只需在映射中添加identificationPredicate,指定确切的实体:

    parentMapping.identificationPredicate = [NSPredicate predicateWithFormat:@"entity == %@", parentMapping.entity];