核心数据& RestKit:与同一对象的多重关系

时间:2014-07-31 14:49:56

标签: ios objective-c core-data restkit rkobjectmapping

我遇到了从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不支持将多个关系保存到同一个对象,因为它使用了NSSetNSOrderedSet)。它忽略了所有双重对象。

有谁知道如何解决问题?

我的尝试失败了:

1)。 我插入了一个新的核心数据表(AB),其中包括:

  1. 引用了A
  2. 有一个位置字段
  3. 引用A
  4. 中的一个B.

    enter image description here

    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' 但我总是使用相同的上下文。

    如果你没有更好的主意,你有解决这个问题的方法吗?

1 个答案:

答案 0 :(得分:0)

您提出的模型结构对于您的重复数据要求是一个明智的解决方案。你应该做的唯一改变是确保所有关系都是双重结束(具有反向)并具有适当的多样性。确保从BAB的关系是多对的。从AAB的关系也应该是很多。

这样做的一般方法是使用多个响应描述符:

  1. 一个用于创建A对象和AB个对象,关键路径为nil
  2. 创建B个对象而不重复,关键路径为Bs
  3. 创建A对象的响应描述符具有嵌套关系映射,以创建具有重复和顺序的AB对象 - 为此,您不能使用AB的任何标识属性和你需要RestKit提供的use the mapping metadata

    一旦创建了对象,就需要连接它们,然后用foreign key mapping完成。这意味着在AB个实例上存储一个transient属性,该属性包含相应B对象的id并使用它来建立连接。

    请注意,更新后,由于此操作,您可能在数据存储中有一些孤立对象(因为您不能使用AB的标识属性),您应该考虑创建一个要清除的获取请求块他们出去(或定期自己做)。