【问题标题】:Core Data & RestKit: Multiple relation to same objectCore Data & RestKit:同一个对象的多重关系
【发布时间】:2014-07-31 14:49:56
【问题描述】:

我遇到了从JSON 字符串到NSManagedObject 的对象映射问题。我通过getObject 请求和核心数据集成使用RestKit。我想自动映射 JSON 响应。

1.) 我从网络服务中得到以下响应(“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),其中:

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

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

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

【问题讨论】:

  • 你使用的上下文是什么?您将需要在后台线程上使用为导入创建的后台上下文......我通常不会赞成这种方法。

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


【解决方案1】:

您提出的模型结构是满足重复数据需求的明智解决方案。您应该在那里进行的唯一更改是确保所有关系都是双端的(具有逆向关系)并具有适当的多重性。确保从BAB 的关系是对多的。从AAB 的关系也应该是对多的。

对此的一般方法是使用多个响应描述符:

  1. 一个创建A对象和AB对象,关键路径是nil
  2. 一个创建B对象不重复,关键路径是Bs

用于创建A 对象的响应描述符具有嵌套关系映射,以创建具有重复和顺序的AB 对象-为此,您不能对AB 使用任何标识属性,您需要use the mapping metadata由 RestKit 提供。

一旦创建了对象,就需要连接它们,这将通过foreign key mapping 完成。这意味着在 AB 实例上存储一个瞬态属性,其中包含适当 B 对象的 id 并使用它来建立连接。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多