Question

I'm struggling to find a way to map some JSON into RestKit. This is an example of what I'm looking at:

       "results":{
           "Test1":[
              {
                 "id":1,
                 "name":"Test 1 here.",
                 "language":"English",
                 "type: "Test1"
              }
           ],
           "Test2":[
              {
                 "id":3,
                 "name":"Another test 2",
                 "language":"English",
                 "type":"Test2"
              },
              {
                 "id":8,
                 "name":"More test 2",
                 "language":"English",
                 "type":"Test2"
              },
              {
                 "id":49,
                 "name":"foo",
                 "language":"English",
                 "type":"Test2"
              }
           ]
        }

Ideally, the JSON wouldn't include the extra redundant layer of "type" as a key, but such is life.

I'd want RestKit to return 4 objects under "results" of type:

@interface Test : NSObject

@property (nonatomic, copy) NSNumber *testId;
@property (nonatomic, copy) NSString *testName;
@property (nonatomic, copy) NSString *testLanguage;
@property (nonatomic, copy) NSString *testType;

I've tried different combinations of mappings such as:

RKObjectMapping *testMapping = [RKObjectMapping mappingForClass:[Test class]];
testMapping.forceCollectionMapping = YES;
[testMapping addAttributeMappingFromKeyOfRepresentationToAttribute:@"testType"];
[testMapping addAttributeMappingsFromDictionary:@{
                                                      @"(testType).id": @"testId",
                                                      @"(testType).name": @"testName",
                                                      @"(testType).language": @"testLanguage",
                                                      }];

but it still fails because its not a single object under the "type" JSON key - it is an array of Test objects.

Is there a way to represent this mapping in RestKit? Or if not, be able to override some callback functions so I can make it work? Unfortunately, I can't change the JSON data coming from the server

Was it helpful?

Solution

I'd say your best bet is to create a response descriptor with a key path of @"results" and a dynamic mapping. That mapping would return a mapping which maps into an NSDictionary and which has a number of relationships defined. This dictionary is just a container to facilitate the other mappings (the relationships).

The relationships are created by iterating the keys of the representation provided to the dynamic mapping and creating one relationship per iteration, using the testMapping, but without the addAttributeMappingFromKeyOfRepresentationToAttribute as you can now use direct attribute access (and the inner type attribute).

Using setObjectMappingForRepresentationBlock:, your block is provided with the representation, which in your case is an NSDictionary of the deserialised JSON. Inside the block you create a mapping just as you usually would, but with the contents based on the keys in the dictionary.


RKObjectMapping *testMapping = [RKObjectMapping mappingForClass:[Test class]];
[testMapping addAttributeMappingsFromDictionary:@{ @"id": @"testId", @"name": @"testName" }];

[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) {
    RKObjectMapping *testListMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
    for (NSString *key in representation) {
        [testListMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeypath:key toKeyPath:key withMapping:testMapping];
    }

    return testListMapping;
}];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top