我正在使用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
找到了解决此问题的解决方案(请参阅下面的答案)。不过,这是我的模型:
我记录了执行以下获取请求的商店内容:
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[UHDNewsCategory entityName]];
fetchRequest.includesSubentities = YES;
在JSON请求之前,商店中没有对象。之后,服务器响应中的每个UHDNewsSource
(= Child
)都有一个UHDNewsCategory
(= Parent
)对象。
答案 0 :(得分:0)
我找到了解决此问题的方法,但它认为默认的RestKit实现并不像预期的那样工作。
只需在映射中添加identificationPredicate
,指定确切的实体:
parentMapping.identificationPredicate = [NSPredicate predicateWithFormat:@"entity == %@", parentMapping.entity];