我有一个拥有用户的应用程序.用户属于帐户.一个帐户可以有多个项目,在这些项目中,Account.Users的一个子集通过“协作”对象分配为协作者.我检索此信息并使用RestKit将其存储在CoreData中,但是我在连接关系时遇到了一些问题 – 可能是由于存储对象的顺序.
我的项目JSON看起来像这样:
{
"id": 1,
"name": "Some Project Name",
"collaborations": [
{
"id": 1,
"collaborator_id": 1,
"permission_group_ids": [ 1, 2 ]
},
{
"id": 2,
"collaborator_id": 2,
"permission_group_ids": [ 2, 3 ]
}
],
"permission_groups": [
{
"id": 1,
"name": "Admin"
},
{
"id": 2,
"name": "Manager"
},
{
"id": 3,
"name": "Employee"
}
]
}
现在,正如您所看到的,我已经嵌套了对此Project特有的其他对象的引用.每个协作者都属于一组特定于项目的权限组.我有一个合作的映射(该类在内部称为ProjectCollaborator),如下所示.我在应用程序的其他地方成功使用了类似的代
// These mappings (and others) work fine.
[map addAttributeMappingsFromDictionary:@{@"permission_group_ids" : @"permissionGroupIds"}];
[map addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"collaborator" withMapping:[User collaboratorMapping]]];
// This mapping works fine in other places, but not here.
NSEntityDescription *entity = [NSEntityDescription entityForName:[self entityName] inManagedObjectContext:[RKObjectManager sharedManager].managedObjectStore.mainQueueManagedObjectContext];
NSRelationshipDescription *groupRelationship = [entity relationshipsByName][@"permissionGroups"];
RKConnectionDescription *connection = [[RKConnectionDescription alloc] initWithRelationship:groupRelationship attributes:@{@"permissionGroupIds" : @"serverId"}];
[map addConnection:connection];
我的请求设置如下.
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:[RKObjectManager sharedManager].responseDescriptors];
共享管理器上的响应描述符添加如下:
[[RKObjectManager sharedManager] addResponseDescriptorsFromArray:@[...
[RKResponseDescriptor responseDescriptorWithMapping:[Project showResponseMapping] method:RKRequestMethodGET pathPattern:@"projects/:serverId" keyPath:@"project" statusCodes:successCodes]
...]];
这是项目showResponseMapping的相关部分:
+(RKEntityMapping *) showResponseMapping
{
static RKEntityMapping* map = nil;
if (map == nil)
{
map = [RKEntityMapping mappingForEntityForName:[self entityName] inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]];
map.identificationAttributes = @[ @"serverId" ];
[map addAttributeMappingsFromDictionary:@{ @"name" : @"name" }];
[map addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"permission_groups" toKeyPath:@"permissionGroups" withMapping:[PermissionGroup mapping]]];
[map addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"collaborations" toKeyPath:@"collaborations" withMapping:[ProjectCollaborator mapping]]];
}
return map;
}
我面临的问题是,从不设置collaboration.permissionGroups关系 – 具体来说,该属性的NSSet为空.我的permissionGroupIds属性已正确填充,正确设置了与用户的关系(collaboration.collaborator).我使用类似的ID数组策略引用其他响应中的现有对象,并成功地进行映射.
我怀疑正在发生的是首先处理协作密钥,并且正在存储协作密钥的所有子代,但是找不到具有提供的ID的相关PermissionGroup,因此放弃了建立关系的尝试.稍后,映射permission_groups键并存储这些组.我有单元测试,确认正确存储PermissionGroup对象.
在我看来,有两个解决这个问题的方法,我都找不到办法 – 如果可能的话,我更喜欢第一个选项:
>我可以指定解析密钥的顺序(我已经尝试在不同的顺序中添加映射)
>我可以让RestKit(或CoreData?)在CoreData中创建一个’空’对象,稍后当填充permission_groups键时会填充该对象
这些选项中的任何一个都可以,还是有更好的解决方案?
最佳答案 理想情况下,RK从所有映射中获取所有连接映射来处理并在最后运行它们,但我还没有检查是否是这种情况.
如果没有,并且看起来不是您的情况,那么您需要确保在尝试连接它们之前创建所有对象.
这是我在你的确切配置中没有尝试过的东西,但是我会尝试创建另外两个响应描述符并将它们放在当前的数组之前.每个人都将使用内部映射(group然后是collab),并使用keypath钻取到相关的数据数组.
主要问题是我没有检查请求操作(或者它将启动的映射操作)是否按顺序使用响应描述符数组.如果确实如此,那么将创建所有内部对象,然后将创建项目并将其连接到它们,然后它们将相互连接.