【问题标题】:Restkit map the response to a parent Entity - when response does not have parent entity valuesRestkit 将响应映射到父实体 - 当响应没有父实体值时
【发布时间】:2016-10-22 19:36:12
【问题描述】:

我在我的项目中使用 RestKit 0.2 版本。我有一种情况,我需要将响应映射到已经保存的父实体。

我的父类是对话,对话可以有很多消息。

首先,我将 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**]];

但是如何创建对话映射?

已编辑 - 尝试使用路由和元数据

正如@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将在用户从对话列表中选择一个对话时发送。

但对话仍未正确映射到消息。

&我只能调用一次这个方法,然后我得到以下错误。

原因:'无法添加与现有路线同名的路线。'

但它应该对所有对话都可用,每当用户选择对话时,都会调用此方法。

解决方案

在映射会话中的消息之前,我使用响应描述符来映射会话和用户。因此,当我对对话中的消息使用响应描述符时,它被映射到先前定义的描述符。

所以我不得不使用 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 );
                                                         }];

【问题讨论】:

    标签: ios json core-data restkit restkit-0.20


    【解决方案1】:

    您应该真正使用路由,以便您可以使用路径模式来插入对话 id。然后可以使用映射元数据访问映射中的 id 值,并使用它连接到相应的对象。

    【讨论】:

    • 我试过你的建议,但我还是没有运气。你能看看我的编辑吗?
    • 您多久致电一次addRoute?您应该在应用启动时设置一次所有路线和映射,而不是重复设置
    • 但我该怎么做。可以有新的对话&用户可以发送新消息,所以用户必须进入对话才能看到消息。所以我无法说出确切的时间。该方法每次都会调用,用户从列表中选择一个对话。
    • 对象管理器的配置应该和你的视图控制器无关。一个糟糕的实现会在应用程序委托中完成,一个好的解决方案应该有一个自定义的特定类
    猜你喜欢
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多