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

时间:2014-03-12 05:48:11

标签: ios iphone json restkit foursquare

我希望将我的所有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个列表。最后,我想将这两个列表合并为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:]:此类不是键值属性的关键值编码兼容。'

我应该使用RKDynamicMappings吗?有没有一些技巧可以解析一个像这样的样式的响应?

2 个答案:

答案 0 :(得分:1)

对于那些感兴趣的人,我对RKResponseDescriptor

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

查看集合操作@distinctUinionOfArrays最终得到了我所需要的东西。它组成了两组数组的联合,然后我从数组联合中的每个对象中获取项密钥。

答案 1 :(得分:0)

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

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

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

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