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

How to handle RestKit nested array of ID references to objects that don't exist yet?

我有一个有用户的应用程序。用户属于一个帐户。一个帐户可以有多个项目,在这些项目中,Account.Users 的一个子集通过 'Collaboration' 对象分配为协作者。我检索此信息并使用 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"
    }
  ]
}

现在,如您所见,我嵌套了对特定于此项目的其他对象的引用。每个协作者都属于特定于项目的一组权限组。我的协作映射(class 在内部称为 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 密钥首先被处理,并且所有子项都被存储,但是相关的 PermissionGroups 与提供的找不到 ID,因此放弃建立关系的尝试。稍后,映射 permission_groups 键并存储这些组。我有确认 PermissionGroup 对象被正确存储的单元测试。

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

这两种选择是否可行,或者是否有更好的解决方案?

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

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

这是我没有在您的确切配置中尝试过的东西,但我会尝试创建 2 个其他响应描述符并将它们放在您当前的响应描述符之前的数组中。每个人都将使用内部映射(分组然后协作)并使用键路径钻取关联的数据数组。

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