Restkit 将响应映射到 parent 实体 - 当响应没有 parent 实体值时
Restkit map the response to a parent Entity - when response does not have parent entity values
我在我的项目中使用 RestKit 0.2 版本。我有一种情况需要将响应映射到已保存的 parent 实体。
我的ParentClass是对话&对话可以有很多消息。
首先,我将 Coredata 中的所有对话保存在 Conversation 实体下。
然后我调用这个 url 来获取与特定对话相关的所有消息。
http://myUrl/conversations/bdc34e2a-fa1f-4dbe-83b4-3296ff657e93/messages
bdc34e2a-fa1f-4dbe-83b4-3296ff657e93 是我的会话 ID
这是我的 json 回复。
[
{
"id":"5f67f6f5-934d-403e-ac64-19dbd4defeda",
"sent_at":"2016-06-08T12:24:28+0000",
"read_at":null,
"sender":{ },
"content":"test message",
"attachment":{ }
},
{
"id":"c4d18b33-4c54-4e7e-a964-a5cedc087122",
"sent_at":"2016-06-08T09:59:41+0000",
"read_at":null,
"sender":{ },
"content":"abc test message",
"attachment":{ }
},
我的 Json 回复没有对话 属性,但我需要将我的所有消息映射到相关对话下。
RKEntityMapping *messageMapping = [RKEntityMapping mappingForEntityForName:[Message entityName] inManagedObjectStore:[[DataStoreManager sharedManager] managedObjectStore]];
[messageMapping addAttributeMappingsFromDictionary:@{
@"id":@"identifier",
@"sent_at": @"date",
@"content": @"message",
}];
messageMapping.identificationAttributes = @[@"identifier"];
我有多对一消息与对话的关系。
[messageMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"conversation" withMapping:**conversationMapping**]];
但是我该如何创建 conversationMapping 呢?
Edited - Trying with routing & meta data
正如@Wain 所建议的,我正在尝试使用 restkit 路由
// conversation mapping
RKEntityMapping *conversationMapping = [RKEntityMapping mappingForEntityForName:[Conversation entityName] inManagedObjectStore:[[BADataStoreManager sharedManager] managedObjectStore]];
[conversationMapping addAttributeMappingsFromDictionary:@{
@"@metadata.routing.parameters.identifier": @"identifier"
}];
conversationMapping.identificationAttributes = @[@"identifier"];
[messageMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"messages" withMapping:conversationMapping]];
这是我的响应描述符
RKResponseDescriptor *conversationDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[EntityMappingProvider messagesResponseMapping] method:RKRequestMethodAny pathPattern:@"/conversations/:identifier/messages" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[[DataStoreManager sharedManager].router.routeSet addRoute:[RKRoute routeWithName:@"conversations" pathPattern:@"/conversations/:identifier/messages" method:RKRequestMethodGET]];
[[DataStoreManager sharedManager] addResponseDescriptor:conversationDescriptor];
[[DataStoreManager sharedManager] getObjectsAtPathForRouteNamed:@"conversations" object:conversation parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
RKLogInfo(@"response %@",mappingResult);
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
RKLogInfo(@"error response %@", error.localizedDescription );
}];
object:conversation 将在用户 select 会话列表中有一个会话时发送。
但对话仍未正确映射到消息。
& 我只能调用此方法一次,然后出现以下错误。
reason: 'Cannot add a route with the same name as an existing route.'
但它应该可用于所有对话,只要用户 select 进行对话,就会调用此方法。
Solution
在映射对话中的消息之前,我使用响应描述符来映射对话和用户。因此,当我为对话中的消息使用响应描述符时,它被映射到先前定义的描述符。
所以我不得不使用 pathPattern 并指定响应描述符,然后它正确映射,正如@Wain 解释的那样,我已经初始化了所有响应描述符一次并多次使用 getObjectsAtPathForRouteNamed .
最后是我的对话映射及其响应描述符
// conversation mapping
RKEntityMapping *conversationMapping = [RKEntityMapping mappingForEntityForName:[Conversation entityName] inManagedObjectStore:[[BADataStoreManager sharedManager] managedObjectStore]];
[conversationMapping addAttributeMappingsFromDictionary:@{
@"@metadata.routing.parameters.identifier": @"identifier"
}];
conversationMapping.identificationAttributes = @[@"identifier"];
[messageMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"messages" withMapping:conversationMapping]];
// Response descriptor
RKResponseDescriptor *conversationDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[EntityMappingProvider messagesResponseMapping] method:RKRequestMethodAny pathPattern:@"/conversations/:identifier/messages" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[[DataStoreManager sharedManager].router.routeSet addRoute:[RKRoute routeWithName:@"conversations" pathPattern:@"/conversations/:identifier/messages" method:RKRequestMethodGET]];
[[DataStoreManager sharedManager] addResponseDescriptor:conversationDescriptor];
[[DataStoreManager sharedManager] getObjectsAtPathForRouteNamed:@"conversations" object:conversation parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
RKLogInfo(@"response %@",mappingResult);
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
RKLogInfo(@"error response %@", error.localizedDescription );
}];
你真的应该使用路由,这样你就可以使用路径模式来插入对话 ID。然后您可以使用映射元数据访问映射中的 id 值并使用它连接到适当的对象。
我在我的项目中使用 RestKit 0.2 版本。我有一种情况需要将响应映射到已保存的 parent 实体。
我的ParentClass是对话&对话可以有很多消息。
首先,我将 Coredata 中的所有对话保存在 Conversation 实体下。
然后我调用这个 url 来获取与特定对话相关的所有消息。
http://myUrl/conversations/bdc34e2a-fa1f-4dbe-83b4-3296ff657e93/messages
bdc34e2a-fa1f-4dbe-83b4-3296ff657e93 是我的会话 ID
这是我的 json 回复。
[
{
"id":"5f67f6f5-934d-403e-ac64-19dbd4defeda",
"sent_at":"2016-06-08T12:24:28+0000",
"read_at":null,
"sender":{ },
"content":"test message",
"attachment":{ }
},
{
"id":"c4d18b33-4c54-4e7e-a964-a5cedc087122",
"sent_at":"2016-06-08T09:59:41+0000",
"read_at":null,
"sender":{ },
"content":"abc test message",
"attachment":{ }
},
我的 Json 回复没有对话 属性,但我需要将我的所有消息映射到相关对话下。
RKEntityMapping *messageMapping = [RKEntityMapping mappingForEntityForName:[Message entityName] inManagedObjectStore:[[DataStoreManager sharedManager] managedObjectStore]];
[messageMapping addAttributeMappingsFromDictionary:@{
@"id":@"identifier",
@"sent_at": @"date",
@"content": @"message",
}];
messageMapping.identificationAttributes = @[@"identifier"];
我有多对一消息与对话的关系。
[messageMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"conversation" withMapping:**conversationMapping**]];
但是我该如何创建 conversationMapping 呢?
Edited - Trying with routing & meta data
正如@Wain 所建议的,我正在尝试使用 restkit 路由
// conversation mapping
RKEntityMapping *conversationMapping = [RKEntityMapping mappingForEntityForName:[Conversation entityName] inManagedObjectStore:[[BADataStoreManager sharedManager] managedObjectStore]];
[conversationMapping addAttributeMappingsFromDictionary:@{
@"@metadata.routing.parameters.identifier": @"identifier"
}];
conversationMapping.identificationAttributes = @[@"identifier"];
[messageMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"messages" withMapping:conversationMapping]];
这是我的响应描述符
RKResponseDescriptor *conversationDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[EntityMappingProvider messagesResponseMapping] method:RKRequestMethodAny pathPattern:@"/conversations/:identifier/messages" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[[DataStoreManager sharedManager].router.routeSet addRoute:[RKRoute routeWithName:@"conversations" pathPattern:@"/conversations/:identifier/messages" method:RKRequestMethodGET]];
[[DataStoreManager sharedManager] addResponseDescriptor:conversationDescriptor];
[[DataStoreManager sharedManager] getObjectsAtPathForRouteNamed:@"conversations" object:conversation parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
RKLogInfo(@"response %@",mappingResult);
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
RKLogInfo(@"error response %@", error.localizedDescription );
}];
object:conversation 将在用户 select 会话列表中有一个会话时发送。
但对话仍未正确映射到消息。
& 我只能调用此方法一次,然后出现以下错误。
reason: 'Cannot add a route with the same name as an existing route.'
但它应该可用于所有对话,只要用户 select 进行对话,就会调用此方法。
Solution
在映射对话中的消息之前,我使用响应描述符来映射对话和用户。因此,当我为对话中的消息使用响应描述符时,它被映射到先前定义的描述符。
所以我不得不使用 pathPattern 并指定响应描述符,然后它正确映射,正如@Wain 解释的那样,我已经初始化了所有响应描述符一次并多次使用 getObjectsAtPathForRouteNamed .
最后是我的对话映射及其响应描述符
// conversation mapping
RKEntityMapping *conversationMapping = [RKEntityMapping mappingForEntityForName:[Conversation entityName] inManagedObjectStore:[[BADataStoreManager sharedManager] managedObjectStore]];
[conversationMapping addAttributeMappingsFromDictionary:@{
@"@metadata.routing.parameters.identifier": @"identifier"
}];
conversationMapping.identificationAttributes = @[@"identifier"];
[messageMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"messages" withMapping:conversationMapping]];
// Response descriptor
RKResponseDescriptor *conversationDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[EntityMappingProvider messagesResponseMapping] method:RKRequestMethodAny pathPattern:@"/conversations/:identifier/messages" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[[DataStoreManager sharedManager].router.routeSet addRoute:[RKRoute routeWithName:@"conversations" pathPattern:@"/conversations/:identifier/messages" method:RKRequestMethodGET]];
[[DataStoreManager sharedManager] addResponseDescriptor:conversationDescriptor];
[[DataStoreManager sharedManager] getObjectsAtPathForRouteNamed:@"conversations" object:conversation parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
RKLogInfo(@"response %@",mappingResult);
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
RKLogInfo(@"error response %@", error.localizedDescription );
}];
你真的应该使用路由,这样你就可以使用路径模式来插入对话 ID。然后您可以使用映射元数据访问映射中的 id 值并使用它连接到适当的对象。