在 Foursquare 的 Lists API 上使用 RKDynamicMapping 来捕获列表

Posted

技术标签:

【中文标题】在 Foursquare 的 Lists API 上使用 RKDynamicMapping 来捕获列表【英文标题】:Using RKDynamicMapping on Foursquare's Lists API to capture lists 【发布时间】:2014-03-12 05:48:11 【问题描述】:

我希望将我的所有 Foursquare 列表都放入 Core Data。我想用 Restkit 来完成这个。 /v2/users/self/lists 响应的结构是:

 "response": 
    "lists": 
        "count": 8,
        "groups": [
            
                "type": "created",
                "name": "Lists You've Created",
                "count": 6,
                "items": [
                    
                        "id": "13250/todos",
                        "name": "My to-do list", ...
                        
                    
                      "id": "13251/something",
                        "name": "Some List", ...
                    ,
                    
                      "id": "13252/somethingelse",
                        "name": "Some Other List", ...
                    
                ]
            ,
            
                "type": "followed",
                "name": "Lists You've Saved",
                "count": 1,
                "items": [
                    
                        "id": "5105e3cae4b0e721ca7b400a",
                        "name": "Portland's Best Coffee - 2012", ...
                      
                     
                      ...
                    
                ]
            
        ]
    

如您所见,keyPath response.lists.groups 下有 2 个列表。最终,我想将这 2 个列表合并为 1 个,但我很乐意获得 2 个单独的列表。

我的映射设置如下:

RKEntityMapping* listMapping = [RKEntityMapping mappingForEntityForName:[FOFSList entityName]
                                                   inManagedObjectStore:objectManager.managedObjectStore];
[listMapping addAttributeMappingsFromDictionary:@
                                                     @"id": @"listID",
                                                     @"title": @"name",
                                                     @"description": @"desc",
                                                     @"user": @"user",
                                                     @"following": @"following",
                                                     @"collaborative": @"collaborative",
                                                     @"canonicalUrl": @"canonicalUrl",
                                                     @"venueCount": @"venueCount",
                                                     @"visitedCount": @"visitedCount"
                                                     ];

RKDynamicMapping *dynamicMapping = [RKDynamicMapping new];
[listMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil
                                                                            toKeyPath:@"items"
                                                                          withMapping:dynamicMapping]];

RKResponseDescriptor *listResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:listMapping
                                                                                         method:RKRequestMethodGET
                                                                                       pathPattern:nil
                                                                                           keyPath:@"response.lists.groups"
                                                                                       statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:listResponseDescriptor];
[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) 
    if ([[representation valueForKey:@"type"] isEqualToString:@"created"]) 
        return listMapping;
     else if ([[representation valueForKey:@"type"] isEqualToString:@"followed"]) 
        return listMapping;
    

    return nil;
];

listMapping.identificationAttributes = @[ @"listID" ];

我最终得到一个错误:

* 由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[valueForUndefinedKey:]:此类与键 propertyMappings 的键值编码不兼容。”

我应该使用 RKDynamicMappings 吗?在解析这样样式的响应时,我是否缺少一些技巧?

【问题讨论】:

【参考方案1】:

对于那些感兴趣的人,我对RKResponseDescriptor 有点创意

 RKResponseDescriptor *listResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:listMapping
                                                                                            method:RKRequestMethodGET
                                                                                       pathPattern:nil
                                                                                           keyPath:@"response.lists.groups.@distinctUnionOfArrays.items"
                                                                                       statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

请参阅收集操作@distinctUinionOfArrays 最终让我得到了我需要的东西。它对 2 个组数组进行联合,然后我从数组联合中的每个对象中获取 items 键。

【讨论】:

【参考方案2】:

目前,动态映射用作类型的过滤器。如果这是您想要的并且是实现过滤器的正确方法,那很好。但是,您以错误的方式应用该映射。

动态映射应作为响应描述符的映射提供。它分析传入的对象并返回要应用的适当映射。

您需要一个新的非动态映射来处理嵌套的items

在映射期间无法处理有关合并的其他问题,但可以通过向目标类添加一个方法来完成,该方法使用映射数组调用,它与现有数组合并并将合并结果推送到真正的实例变量。映射目标将是方法而不是实例变量。

【讨论】:

您提到:“您需要一个新的、非动态的映射来处理嵌套项。”。这就是“listMapping”的作用。它用于映射动态映射找到的各个对象。我是不是误读了你的意思?

以上是关于在 Foursquare 的 Lists API 上使用 RKDynamicMapping 来捕获列表的主要内容,如果未能解决你的问题,请参考以下文章

Foursquare 场地搜索 API:如何找到最近的场地?

foursquare API的IP地址范围是多少? [关闭]

适用于 iPhone 的 FourSquare API

如何对foursquare场所/搜索api返回的结果进行分页?

为Leaflet解析Foursquare API JSON

Foursquare Tips:网站上API和Explore的区别