如何处理对尚不存在的对象的 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 对象被正确存储的单元测试。
在我看来,这个问题有两个解决方案,但我都找不到解决方法 - 如果可能的话,我更喜欢第一个选项:
- 我可以指定解析键的顺序(我已经尝试以不同的顺序添加映射)
- 我可以让 RestKit(或 CoreData?)在 CoreData 中创建一个 'empty' 对象,稍后将在填充
permission_groups
键时填充该对象
这两种选择是否可行,或者是否有更好的解决方案?
理想情况下,RK 从所有映射中获取所有连接映射来处理并在最后运行它们,但我没有检查是否是这种情况。
如果没有,从你的情况来看似乎不是,那么你需要确保在尝试连接它们之前创建所有对象。
这是我没有在您的确切配置中尝试过的东西,但我会尝试创建 2 个其他响应描述符并将它们放在您当前的响应描述符之前的数组中。每个人都将使用内部映射(分组然后协作)并使用键路径钻取关联的数据数组。
主要问题是我没有检查请求操作(或者说它将启动的映射操作)是否按顺序使用响应描述符数组。如果是,则将创建所有内部对象,然后将创建项目并连接到它们,然后它们将相互连接。
我有一个有用户的应用程序。用户属于一个帐户。一个帐户可以有多个项目,在这些项目中,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 对象被正确存储的单元测试。
在我看来,这个问题有两个解决方案,但我都找不到解决方法 - 如果可能的话,我更喜欢第一个选项:
- 我可以指定解析键的顺序(我已经尝试以不同的顺序添加映射)
- 我可以让 RestKit(或 CoreData?)在 CoreData 中创建一个 'empty' 对象,稍后将在填充
permission_groups
键时填充该对象
这两种选择是否可行,或者是否有更好的解决方案?
理想情况下,RK 从所有映射中获取所有连接映射来处理并在最后运行它们,但我没有检查是否是这种情况。
如果没有,从你的情况来看似乎不是,那么你需要确保在尝试连接它们之前创建所有对象。
这是我没有在您的确切配置中尝试过的东西,但我会尝试创建 2 个其他响应描述符并将它们放在您当前的响应描述符之前的数组中。每个人都将使用内部映射(分组然后协作)并使用键路径钻取关联的数据数组。
主要问题是我没有检查请求操作(或者说它将启动的映射操作)是否按顺序使用响应描述符数组。如果是,则将创建所有内部对象,然后将创建项目并连接到它们,然后它们将相互连接。