1
votes

I have following JSON:

{
    "stream": [{
        "catalog": {}
    }, {
        "catalog": {}
    }, {
        "user": {}
    }]
}

with following mapping rules:

[RKResponseDescriptor responseDescriptorWithMapping:catalogMapping
                                        pathPattern:nil keyPath:@"stream.catalog"
                                        statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];

[RKResponseDescriptor responseDescriptorWithMapping:userMapping
                                        pathPattern:nil keyPath:@"stream.user"
                                        statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];

Mapping works fine until multiple type of object are in the stream. When stream contain multiple objects, say user and catalog restkit fails this assert:

NSCAssert([representation isKindOfClass:[NSDictionary class]], @"Expected a dictionary representation");

Is there a way map that structure?

1
So sometimes "stream" is a dictionary in the JSON and sometimes it's an array? - Wain
it is always an array of dictionaries. - Ivan
in that case stream is an array, not a dictionary? meaning stream is an array? - Kevin R

1 Answers

3
votes

I had a luxury to request an API change so we moved to

{
    "stream": [{
        "type": "catalog",
        "other": "fields"
    }, {
        "type": "catalog"
        "other": "fields"
    }, {
        "type": "user"
        "other": "fields"
    }]
}

An now I use dynamic mapping:

    RKDynamicMapping* dynamicMapping = [RKDynamicMapping new];
    [dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) {
        if ([[representation objectForKey:@"type"] isEqualToString:@"catalog"]) {
            return catalogMapping;
        } else if ([[representation objectForKey:@"type"] isEqualToString:@"user"]) {
            return userMapping;
        }
//       ...
    }];


    [manager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:dynamicMapping
                                                                           pathPattern:nil keyPath:@"stream"
                                                                           statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];