我遇到了从JSON
字符串到NSManagedObject
的对象映射问题。我通过RestKit
请求和核心数据集成使用getObject
。我想自动映射JSON响应。
1)。 我从Web服务获得以下响应(“A”对象):
{
"Bs":[
{ "id" : "abc", "name" : "name 1"},
{ "id" : "def", "name" : "name 2"}
{ "id" : "abc", "name" : "name 1"},
],
"id": "1"
}
2)。 此响应具有有序值(B对象),有时同一对象(“id”:“abc”)不止一次。此外,项目的顺序很重要。
3)。
Core-Data不支持将多个关系保存到同一个对象,因为它使用了NSSet
(NSOrderedSet
)。它忽略了所有双重对象。
有谁知道如何解决问题?
我的尝试失败了:
1)。 我插入了一个新的核心数据表(AB),其中包括:
2)。
我尝试使用RKValueTransformer
实例映射对象。
这将迭代B实例的JSON
响应,并使用当前位置创建AB对象。这些对象保存在NSSet
中,从自定义值转换器
RKValueTransformer *aabbTransformer = [RKBlockValueTransformer valueTransformerWithValidationBlock:^BOOL(__unsafe_unretained Class sourceClass, __unsafe_unretained Class destinationClass) {
return ([sourceClass isSubclassOfClass:[NSArray class]] && [destinationClass isSubclassOfClass:[NSOrderedSet class]]);
} transformationBlock:^BOOL(id inputValue, __autoreleasing id *outputValue, Class outputValueClass, NSError *__autoreleasing *error) {
// Validate the input and output
RKValueTransformerTestInputValueIsKindOfClass(inputValue, [NSArray class], error);
RKValueTransformerTestOutputValueClassIsSubclassOfClass(outputValueClass, [NSOrderedSet class], error);
NSMutableOrderedSet *outputSet = [[NSMutableOrderedSet alloc] init];
NSInteger pos = 1;
for (id b in inputValue) {
// see JSON output at the top
// B instance already exists in core data persistent store
NSString *bid = [b valueForKeyPath:@"id"];
B *b = [B bById:bid];
// create AB instance
AB *ab = [NSEntityDescription ...]
ab.b = b;
ab.position = [NSNumber numberWithInteger:pos];
[outputSet addObject:ab];
pos++;
}
// return for A.abs
*outputValue = [[NSOrderedSet alloc] initWithOrderedSet:outputSet];
return YES;
}];
RKAttributeMapping *aabbMapping = [RKAttributeMapping attributeMappingFromKeyPath:@"bs" toKeyPath:@"abs"];
aabbMapping.valueTransformer = aabbMappingTransformer;
3。)但是我收到一个错误: 非法尝试在不同环境中的对象之间建立关系'abs' 但我总是使用相同的上下文。
如果你没有更好的主意,你有解决这个问题的方法吗?
答案 0 :(得分:0)
您提出的模型结构对于您的重复数据要求是一个明智的解决方案。你应该做的唯一改变是确保所有关系都是双重结束(具有反向)并具有适当的多样性。确保从B
到AB
的关系是多对的。从A
到AB
的关系也应该是很多。
这样做的一般方法是使用多个响应描述符:
A
对象和AB
个对象,关键路径为nil
B
个对象而不重复,关键路径为Bs
创建A
对象的响应描述符具有嵌套关系映射,以创建具有重复和顺序的AB
对象 - 为此,您不能使用AB
的任何标识属性和你需要RestKit提供的use the mapping metadata。
一旦创建了对象,就需要连接它们,然后用foreign key mapping完成。这意味着在AB
个实例上存储一个transient属性,该属性包含相应B
对象的id并使用它来建立连接。
请注意,更新后,由于此操作,您可能在数据存储中有一些孤立对象(因为您不能使用AB
的标识属性),您应该考虑创建一个要清除的获取请求块他们出去(或定期自己做)。