4

I had been parsing my JSON quite nicely but my server just changed on me. My JSON used to look like this:

{
    "blobs": [  
        {
            "createdOn": "2012-03-16T15:13:12.551Z",
            "description": "Fake description",
            "hint": "And a useless hint",
            "id": 400,
            "name": "Fake CA one",
            "publicId": "FF6",
            "type": 0
        },
        {
            "createdOn": "2012-03-16T17:33:48.514Z",
            "description": "No hint on this one, but it does have a description.",
            "hint": "Hint",
            "id": 402,
            "name": "Second fake one in CA",
            "publicId": "FF8",
            "type": 0
        }
    ]
}

and my mapping looked like this:

RKObjectMapping* blobMapping = [RKObjectMapping mappingForClass:[GetResponseInRegionResponse class]];

[blobMapping mapKeyPath:@"name" toAttribute:@"name"];
[blobMapping mapKeyPath:@"id" toAttribute:@"blobId"];
[blobMapping mapKeyPath:@"description" toAttribute:@"description"];
[blobMapping mapKeyPath:@"hint" toAttribute:@"hint"];

[[RKObjectManager sharedManager].mappingProvider setMapping:blobMapping forKeyPath:@"blobs"];

Now my server has changed and I get this back:

{
    "blobsList": {
        "blobs": [  
            {
                "createdOn" :"2012-03-16T15:13:12.551Z",
                "description": "Fake description",
                "hint": "And a useless hint",
                "id": 400,
                "name": "Fake CA one",
                "publicId": "FF6",
                "type": 0
            },
            {
                "createdOn": "2012-03-16T17:33:48.514Z",
                "description": "No hint on this one, but it does have a description.",
                "hint": "Hint",
                "id": 402,
                "name": "Second fake one in CA",
                "publicId": "FF8",
                "type": 0
            }
        ]
    }
}

So I added this to my mapping:

RKObjectMapping* blobsListMapping = [RKObjectMapping mappingForClass:[GetResponseInRegionResponseList class]];
[blobsListMapping mapKeyPath:@"blobsList" toAttribute:@"blobsList"];

[[RKObjectManager sharedManager].mappingProvider setMapping:blobsListMapping forKeyPath:@"blobsList"];

And are are my Classes:

@interface GetResponseInRegionResponse : NSObject
{
    NSString* name;
    NSString* blobId;
    NSString* description;
    NSString* hint;
}       

@interface GetResponseInRegionResponseList : NSObject
{
    NSArray  *blobsList;
}

When I parse this JSON, I get one object that has a JKArray of 2 objects in it, both of those are JKDictionary objects. So clearly that is my data, but it is in JKDictionary form. It never mapped to the GetResponseInRegionResponse class!

From reading the github docs it looks like I want to use a toRelationship method for arrays, but I'm just not seeing where to put it. If I follow the "articles" example and try this:

[blobListMapping mapKeyPath:@"blobs" toAttribute:@"blobsList"];
[blobListMapping mapKeyPath:@"blobs" toRelationship:@"blobsList" withMapping:blobMapping];

I get this exception:

2012-03-19 14:59:53.704 Ferret[8933:16303] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unable to add mapping for keyPath blobsList, one already exists...'

So how can I map an array of complex objects inside my JSON?

I appreciate any help. Thanks!

2 Answers 2

3

The accepted answer appears to address a version before v0.2, the current version. My solution looks slightly different, code is pasted below:

RKObjectMapping * eventMapping = [RKObjectMapping mappingForClass:[RKJMEvent class]];
[eventMapping addAttributeMappingsFromDictionary:[RKJMEvent map]];
RKObjectMapping * eventResponseMapping =[RKObjectMapping mappingForClass:[RKJMEventsResponse class]];
[eventResponseMapping addAttributeMappingsFromDictionary:[RKJMEventsResponse map]];
[eventResponseMapping addRelationshipMappingWithSourceKeyPath:@"events" mapping:eventMapping];


RKResponseDescriptor *responseDescriptorEventResponse = [RKResponseDescriptor responseDescriptorWithMapping:eventResponseMapping
                                                                                    pathPattern:API_GET_EVENTS_PATH
                                                                                        keyPath:nil
                                                                                    statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptorEventResponse];
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, but that would be clearer if it used the class names, and the key paths, from the question rather than "events", etc.
@murrayc fee free to edit my two year old answer if you think you can make it more useful!
2
+50

Have you tried only changing

    [[RKObjectManager sharedManager].mappingProvider setMapping:blobMapping forKeyPath:@"blobsList.blobs"];

to reflect the changed path to your data array?

7 Comments

When I do that I get:. -- *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<GetResponseInRegionResponse 0x7567250> valueForUndefinedKey:]: this class is not key value coding-compliant for the key id.'
Ahhh, that was my mistake, the JSON had an element tagged with "id" and I had a class member named "blobId" not "id." But I also needed to have the toRelationship part in. I got that off the RestKit mailing list. If that person chimes in here with that part of the problem I see if I can split the bounty between the two of you. Thank you so much!
The way your JSON is set up your don't need a relationship. Inside the object "blobsList" you directly have another object "blobs" and only there you have the array. "blobList" is never going to contain an array if it really is like in your example.
Yeah, I need to check it out some more. Right now my didLoadObject's objects is an array of 3, not 2 objects, the outer object and the 2 inner ones. That's just weird... I'll try it tomorrow. Thanks!
yes. I forgot to mention that you should keep your original setup and only add the single line above - no additional relationship...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.