RestKit 使用指定的主键引用在默认关系中映射对象

Posted

技术标签:

【中文标题】RestKit 使用指定的主键引用在默认关系中映射对象【英文标题】:RestKit Mapping objects within a default relationship using a specified primary key reference 【发布时间】:2012-07-13 14:48:46 【问题描述】:

我目前正在开发一个 ios Messenger 应用程序,我想谈谈这两个类的关系:MessengerConversationMessengerMessage

假设我已经有一个本地 MessengerConversation 实例,它可以有许多与其messages 关系属性相关的 MessengerMessage 实例,我想请求并映射以下 JSON 有效负载:

请求:GET /conversations/:conversationID/msgs 回应:


  "messages": [
    
      ...
      "messageid": n,
      "content": "..."
      ...
    ,
    ...
  ]

由于响应 JSON 有效负载未指示传递的消息来自哪个对话。我使用以下方法将这个问题修复到我的MessengerManager 类(负责与共享的 RKObjectManager 实例交互):

- (void)objectLoader:(RKObjectLoader *)objectLoader willMapData:(inout id *)mappableData 
    //
    // GETs Resource Paths.
    if ([objectLoader method] == RKRequestMethodGET) 

        if ([pathMatcherConversationsMessagesGET matchesPath:objectLoader.resourcePath tokenizeQueryStrings:NO parsedArguments:Nil]) 
            //
            // Get requested conversationID from the following resource path Pattern:
            // kMessengerManagerResourcePathMessages: /conversations/:conversationID/msgs
            NSNumber *currentConversationID = Nil;
            NSDictionary *arguments = Nil;

            BOOL isMatchingPattern = [pathMatcherConversationsMessagesGET matchesPattern:kMessengerManagerResourcePathConversationsMessagesGET 
                                                                    tokenizeQueryStrings:YES 
                                                                         parsedArguments:&arguments];

            if (isMatchingPattern) 
                currentConversationID = [arguments objectForKey:@"conversationID"];
                //
                // Get the original returned array of messages:
                NSArray *origMessagesArray = [*mappableData valueForKeyPath:@"messages"];
                NSMutableArray *reformattedData = [NSMutableArray arrayWithCapacity:[origMessagesArray count]];
                //
                // Create copies of objects adding the already knew reference.
                for (NSDictionary *origMessagesArrayObject in origMessagesArray) 
                    NSMutableDictionary *newMessagesArrayObject = [origMessagesArrayObject mutableCopy];
                    [newMessagesArrayObject setObject:currentConversationID forKey:@"conversationid"];
                    [reformattedData addObject:newMessagesArrayObject];
                
                //
                // Replace the new objects instead of the response objects
                [*mappableData setObject:reformattedData forKey:@"messages"];
            
        
        

所以一切正常。也就是说,所有从指定的 MessengerConversation(到 RKObjectLoader 资源路径中)加载的 MessengerMessages 都被插入到想要的关系中。

现在真正的问题来了,因为我正在使用采用 RKObjectLoaderProtocol 的 MessengerManager 类,我可以实现 objectLoader:willMapData: 方法。但是由于我的 View 类使用RKFetchedResultsTableController 并且每个表控制器实例也是它的 RKObjectLoader 委托,我不知道在映射操作之前启用 RKFetchedResultsTableController 实例来更新接收到的 JSON 有效负载是最佳实践。

我应该继承它吗?

还有更好的方法将接收到的对象映射到由 RKObjectLoader 资源路径指定的预定义对象(例如:GET /conversations/2/msg,其中所有结果消息都应映射到已定义的 MessengerConversation 对象及其主键中值等于 2)?

最好的问候, 皮瓦

【问题讨论】:

【参考方案1】:

你不需要这个方法。当您启动 RKObjectLoader 时,将您的 Conversation 对象设置为 targetObject 并制作相对于该对象的映射。例如:

RKManagedObjectMapping* cMapping = [RKManagedObjectMapping mappingForClass: [MessengerConversation class]];
RKManagedObjectMapping* mMapping = [RKManagedObjectMapping mappingForClass: [MessengerMessage class]];

//Configure mappings

[cMapping mapKeyPath: @"messages" toRelationship: @"messages" withObjectMapping: mMapping];

[mappingProvider setMapping cMapping forKeyPath: @""];

【讨论】:

嗨,保罗,首先,感谢您的回答。它纠正了我的错误,也教会了我一种新的方法。但是在按照您的建议进行更改后,我开始收到以下错误:添加映射错误:无法将对象集合映射到非可变集合。意外的目标对象类型'MessengerConversation' 作为测试,我在MessengerConversation 类中实现了三个方法:addObjectremoveObject e containsObject(只是重定向到它的messages NSSet 属性)和它又开始工作了。是否有可能以更好的方式修复它? 我也有同样的问题。您的 JSON 有效负载是否包含对话 -> 消息数据?如果有效载荷中有对话密钥,RestKit 如何知道将每条消息映射到父对话? 我的意思是如果payload没有对话键? 我还得到“无法将对象集合映射到非可变集合”。有人有这个问题的解决方案吗?我真的需要 targetObject 才能工作! :)

以上是关于RestKit 使用指定的主键引用在默认关系中映射对象的主要内容,如果未能解决你的问题,请参考以下文章

ejb3:用简单的主键映射多对多关系

mybatis一对一关联关系映射

如何使用不同的主键属性更新 RestKit 中的已发布对象?

hibernate中基于主键映射1-1关联关系和基于外键映射1-1关联关系的不同

Rails 3.1 & RestKit 0.9.3 - 引用映射

如何使用 JPA 实现时态表?