如何处理RestKit嵌套的ID引用数组引用到尚不存在的对象?

时间:2015-03-16 11:57:36

标签: ios core-data restkit

我有一个拥有用户的应用。用户属于帐户。一个帐户可以有多个项目,在这些项目中,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]
...]];

这是Project 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数组策略来引用其他响应中的现有对象,并且这些对象的映射成功。

怀疑正在发生的事情是首先处理collaborations密钥,并且正在存储所有子代,但是找不到与提供的ID相关的PermissionGroups,所以建立关系的尝试被放弃了。稍后,映射permission_groups密钥并存储这些组。我有单元测试,确认正确存储了PermissionGroup对象。

在我看来,这个问题有两个解决方案,我都找不到办法 - 如果可能的话,我更喜欢第一个选项:

  • 我可以指定解析密钥的顺序(我已尝试以不同的顺序添加映射)
  • 我可以让RestKit(或CoreData?)创建一个空的' CoreData中的对象将在以后填充permission_groups密钥时填充

这些选项中的任何一个都可以,还是有更好的解决方案?

1 个答案:

答案 0 :(得分:2)

理想情况下,RK从所有映射中获取所有映射的连接映射并在最后运行它们,但我还没有检查是否是这种情况。

如果没有,并且看起来不是你的情况,那么你需要确保在尝试连接它们之前创建所有对象。

这是我在你的确切配置中没有尝试过的东西,但是我会尝试创建另外两个响应描述符并将它们放在当前的数组之前。每个都使用内部映射(group然后是collab),并使用keypath钻取到相关的数据数组。

主要问题是我没有检查请求操作(或者它将启动的映射操作)是否按顺序使用响应描述符数组。如果确实如此,那么将创建所有内部对象,然后将创建项目并将其连接到它们,然后它们将相互连接。