没有 KVC 的 RestKit 对象映射关系
阅读 RestKit 的 GitHub 上的对象映射指南后,我的问题并没有消失,所以也许有人可以说 RestKit 是否可以处理以下想法。
具有关系的实体
Company
- unitID
- companyID
- name
- contacts* (Company -->> Contact | 1:n)
Contact
- unitID
- companyID
- contactID
- lastName
- firstName
- account* (Contact >--> Company | 1:1)
JSON(公司)
[
{
"unitID":"003CABD8DEB5DC13C",
"companyID":"BSP-002999",
"name":"Testcompany"
}
]
JSON(联系人)
[
{
"unitID":"DAC2ACCC125795D00",
"companyID":"BSP-002999",
"contactID":"CLP-015468",
"firstName":"Mister",
"lastName":"Wayne"
}
]
由于限制,我无法将所属联系人嵌套到公司中(否则我不会写这个),所以我想在导入时映射数据时执行此操作。
问题
是否可以将每个联系人映射到其所属的公司(由属性 companyID 标识)在导入时给定RestKit 的方法?
如果没有,我想知道最好的解决方案。谢谢!
背景
在此应用的第一个版本中,我已将对象映射到给定实体(无关系),并使用谓词 companyID = %@。由于数据量很大(4000 多家公司,7000 多个联系人),获取所有所属联系人大约需要一秒钟 - 所以我想出了使用关系的想法(这与本地虚拟数据完美配合)。
解决方案
在下面给出的答案的帮助下,我当前的映射如下所示(RestKit v.10)。
// Setting up Restkit with objectStore
...
// Init objectMapping for Class Company
companyMapping = [RKManagedObjectMapping mappingForClass:[Company class] inManagedObjectStore:objectStore];
[companyMapping mapKeyPath:@"unitID" toAttribute:@"unitID"];
[companyMapping mapKeyPath:@"companyID" toAttribute:@"companyID"];
[companyMapping mapKeyPath:@"name" toAttribute:@"name"];
companyMapping.setDefaultValueForMissingAttributes = NO;
companyMapping.primaryKeyAttribute = @"companyID";
// Init objectMapping for Class Contact
contactMapping = [RKManagedObjectMapping mappingForClass:[Contact class] inManagedObjectStore:objectStore];
[contactMapping mapKeyPath:@"unitID" toAttribute:@"unitID"];
[contactMapping mapKeyPath:@"companyID" toAttribute:@"companyID"];
[contactMapping mapKeyPath:@"contactID" toAttribute:@"contactID"];
[contactMapping mapKeyPath:@"lastName" toAttribute:@"lastName"];
[contactMapping mapKeyPath:@"firstName" toAttribute:@"firstName"];
contactMapping.setDefaultValueForMissingAttributes = NO;
contactMapping.primaryKeyAttribute = @"contactID";
// Init relationships
[contactMapping mapRelationship:@"company" withMapping:companyMapping];
[contactMapping connectRelationship:@"company" withObjectForPrimaryKeyAttribute:@"companyID"];
// Get objects from server
...
After reading the Object Mapping-Guide on GitHub for RestKit my problem didn't disappear, so perhaps somebody can say if RestKit could deal with the following idea.
Entities with Relationships
Company
- unitID
- companyID
- name
- contacts* (Company -->> Contact | 1:n)
Contact
- unitID
- companyID
- contactID
- lastName
- firstName
- account* (Contact >--> Company | 1:1)
JSON (Company)
[
{
"unitID":"003CABD8DEB5DC13C",
"companyID":"BSP-002999",
"name":"Testcompany"
}
]
JSON (Contact)
[
{
"unitID":"DAC2ACCC125795D00",
"companyID":"BSP-002999",
"contactID":"CLP-015468",
"firstName":"Mister",
"lastName":"Wayne"
}
]
Due to limitations I'm not able to nest the belonging contacts into the companies (otherwise I wouldn't write this), so I want to do this use when the data is mapped on import.
Question
Is it possible to map each Contact to it's belonging Company (identified by the attribute companyID) on import with given methods by RestKit?
If not, I would like to know the best solution for it. Thanks!
Background
In my first build of this app I've mapped the objects to the given entities (without relationships) and fetched all belonging contacts to a company with the predicate companyID = %@. Due to the amount of data (4000+ Companies, 7000+ Contacts) fetching all belonging contacts takes about a second - so I came up with the idea to use relationsships (which works perfect with local dummy data).
Solution
With the help of the given answer below my current mapping looks like the following (RestKit v.10).
// Setting up Restkit with objectStore
...
// Init objectMapping for Class Company
companyMapping = [RKManagedObjectMapping mappingForClass:[Company class] inManagedObjectStore:objectStore];
[companyMapping mapKeyPath:@"unitID" toAttribute:@"unitID"];
[companyMapping mapKeyPath:@"companyID" toAttribute:@"companyID"];
[companyMapping mapKeyPath:@"name" toAttribute:@"name"];
companyMapping.setDefaultValueForMissingAttributes = NO;
companyMapping.primaryKeyAttribute = @"companyID";
// Init objectMapping for Class Contact
contactMapping = [RKManagedObjectMapping mappingForClass:[Contact class] inManagedObjectStore:objectStore];
[contactMapping mapKeyPath:@"unitID" toAttribute:@"unitID"];
[contactMapping mapKeyPath:@"companyID" toAttribute:@"companyID"];
[contactMapping mapKeyPath:@"contactID" toAttribute:@"contactID"];
[contactMapping mapKeyPath:@"lastName" toAttribute:@"lastName"];
[contactMapping mapKeyPath:@"firstName" toAttribute:@"firstName"];
contactMapping.setDefaultValueForMissingAttributes = NO;
contactMapping.primaryKeyAttribute = @"contactID";
// Init relationships
[contactMapping mapRelationship:@"company" withMapping:companyMapping];
[contactMapping connectRelationship:@"company" withObjectForPrimaryKeyAttribute:@"companyID"];
// Get objects from server
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,RestKit 可以在映射时为您补充这种关系。在联系人模型的 RKManagedObjectMapping 上,您需要执行以下操作:
[objectMapping mapRelationship:@"company" withMapping:companyMapping]
[objectMapping connectRelationship:@"company" withObjectForPrimaryKeyAttribute:@"companyID"];
RestKit 完成有效负载映射后,它将通过集合传回并合并任何关系。如果有效负载实际创建了满足连接所需的对象,则处理会推迟到映射之后。
在开发分支上,您可以使用替代工作流程。本周早些时候,我添加了对使用负载中的 ID 数组来维持多对多关系的支持。这将允许您发送属于有效负载中的公司的联系人列表。对于您的用例来说,它可能更有效。
我在 RestKit 邮件列表中发布的帖子的其他详细信息:http://groups.google.com/组/restkit/msg/416951f86b2862d1
Yes, RestKit can hydrate this relationship for you at mapping time. On your RKManagedObjectMapping for your Contact model, you will need to do the following:
[objectMapping mapRelationship:@"company" withMapping:companyMapping]
[objectMapping connectRelationship:@"company" withObjectForPrimaryKeyAttribute:@"companyID"];
After RestKit has completed mapping a payload, it will pass back through the collection and hydrate any relationships. The processing is deferred until after mapping in case the payload actually creates objects that you need to satisfy the connections.
On the development branch, there is an alternative workflow available to you. Earlier this week I added support for hydrating a has-many relationship using an array of ID's in the payload. This would let you send the list of Contacts that belong to a company down in the payload instead. It may be more efficient for your use case.
Additional details from my post to the RestKit mailing list: http://groups.google.com/group/restkit/msg/416951f86b2862d1