RestKit 0.2 映射 Core Data <--> JSON 与一对多关系

Posted

技术标签:

【中文标题】RestKit 0.2 映射 Core Data <--> JSON 与一对多关系【英文标题】:RestKit 0.2 mapping Core Data <--> JSON with to-many relationships 【发布时间】:2013-08-15 16:27:06 【问题描述】:

我已经与 RestKit 斗争了一个多星期,似乎根本无法理解关系映射...我尝试阅读文档和示例,但似乎没有当我尝试在实践中应用它时才有意义。

我暂时放弃了我的应用程序并将所有内容简化为一个简单的独立项目,该项目具有以下数据模型:

模板拥有节点集合。 这些节点的子集在模板中也可以称为“链接”。

生成的类如下所示:

@interface Template : NSManagedObject
@property (nonatomic, retain) NSString * guid;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *links;
@property (nonatomic, retain) NSSet *nodes;
@end

@interface Node : NSManagedObject
@property (nonatomic, retain) NSString * desc;
@property (nonatomic, retain) NSString * guid;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) Template *template;
@end

我正在尝试使用 RestKit 映射将核心数据模型映射到 JSON,并将 JSON 映射回核心数据。最终会有一个服务器组件,但我也想使用相同的映射来支持将 json 导入/导出到文件。

这是我希望 JSON 如何查找模板的示例:

"nodes":[
    "name":"Node 1","guid":"N-0001","desc":"This is the first node",
    "name":"Node 2","guid":"N-0002","desc":"This is the second node",
    "name":"Node 3","guid":"N-0003","desc":"This is the third node"
],
"guid":"T-0001",
"name":"Template 1",
"links":["N-0001","N-0002"]

以下是我目前使用的映射:

self.nodeMapping = [RKEntityMapping mappingForEntityForName:@"Node" inManagedObjectStore:self.rkManagedObjectStore];
[self.nodeMapping addAttributeMappingsFromDictionary:@
    @"guid": @"guid",
    @"name": @"name",
    @"desc": @"desc"
 ];
[self.nodeMapping setIdentificationAttributes:@[@"guid"]];

self.templateMapping = [RKEntityMapping mappingForEntityForName:@"Template" inManagedObjectStore:self.rkManagedObjectStore];
[self.templateMapping addAttributeMappingsFromDictionary:@
    @"guid": @"guid",
    @"name": @"name"
 ];
[self.templateMapping setIdentificationAttributes:@[@"guid"]];

[self.templateMapping addRelationshipMappingWithSourceKeyPath:@"nodes" mapping:self.nodeMapping];

这适用于“节点”关系,但我一生都无法弄清楚如何使用 ID 映射链接。

我试过了

[self.templateMapping addConnectionForRelationship:@"links" connectedBy:@"guid"];

但是当我导入上面的 JSON 时,这只是让 links 属性为空。

我也花了很长时间弄乱了这么多不同形式的关系映射和属性映射,一切都会导致 RestKit 出现神秘错误,或者根本没有发生任何事情。

谁能告诉我我需要在这个映射中添加什么才能正确映射链接?

然后我计划使用相同的映射将核心数据模板转储到 JSON。我希望我可以为此使用 [self.templateMapping inverseMapping] - 但我已经放弃了这个,直到我可以让导入映射工作。

谢谢

【问题讨论】:

【参考方案1】:

在 Restkit 对象映射文档中查看此部分:Mapping Values without Key Paths

我按照您的 JSON 结构为您提供了一个快速示例:

RKEntityMapping *linkNodeMapping = [RKEntityMapping mappingForEntityForName:@"Node" inManagedObjectStore:self.rkManagedObjectStore];
[linkNodeMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"guid"]];
[linkNodeMapping setIdentificationAttributes:@[@"guid"]];
RKRelationshipMapping *linkNodesRelationshipMapping = [RKRelationshipMapping relationshipMappingFromKeyPath:@"links"
                                                                                              toKeyPath:@"links"
                                                                                            withMapping:linkNodeMapping];
[self.templateMapping addPropertyMapping:linkNodesRelationshipMapping];

【讨论】:

谢谢。也许我现在已经盯着这个太久了,但我不完全理解你的例子 - 你添加了一个名为 Link 的新类?目前我仅有的类是模板和节点......链接类适合哪里? 编辑样本以更好地满足您的需求。让我知道它是否有帮助。另一方面,您是否可以控制 JSON 结构?另一种方法是从 JSON 中删除“链接”数组,而是向节点添加“类型”属性,以告知它们是否是节点链接。然后,您可以从模型中删除“链接”关系并使用获取的属性来获取链接。 谢谢!这行得通。我已经尝试过类似的方法,但运气不佳 - 我认为关键是在链接映射上设置标识属性。 实际上,还有最后一个问题.... ;) 映射现在适用于 JSON -> 对象,但是当我使用 inverseMapping 将对象图序列化回 JSON 时,nil 目标键路径导致链接被映射为键值对,每个都有一个空值,而不是链接只是被映射为字符串......即我得到 "links":["N-0001":, "N-0002":] 而不仅仅是 "links":["N-0001","N-0002"]。有没有办法避免这种情况?或者我可以对逆映射做些什么来强制它变成正确的形状吗?

以上是关于RestKit 0.2 映射 Core Data <--> JSON 与一对多关系的主要内容,如果未能解决你的问题,请参考以下文章

Restkit Core Data 映射崩溃应用程序

RestKit 到 Core Data 的映射和加载零对象。 RKManagedObjectLoader

RestKit 0.20.1 将本地 JSON 映射到 Core Data 崩溃

Restkit/Core Data 关系映射,实体到相同类型的实体(父/子)

Core Data + RestKit 映射多对多关系?

RestKit with Core Data - 没有主键的映射