Ravi
Ravi

Reputation: 4009

IOS - RESTKIT - mapping result in multiple ways

I am new to ios/RESTKIT. I am trying to consume a webservice from an ios device using RESTKIT. The json return could have 2 possible outcomes.

A) On Failure, json result looks like this (result is a string "null". Error code available):

{
    status: false,
    result: null
    error: NO_SUCH_USER
}

Mapping for (A)

RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[WsReturn class]];
    [mapping mapKeyPath:@"result" toAttribute:@"result"];
    [mapping mapKeyPath:@"status" toAttribute:@"status"];
    [mapping mapKeyPath:@"error" toAttribute:@"error"];
    [objectManager.mappingProvider setMapping:mapping forKeyPath:@"/"];

B) On Success, it looks like (result is a "complex object". Error code is null):

{
    status: true,
    result: {   
       name: "Some User",
       tasks: [
            {
              name: "Some Task1",
              taskId: 10
            },
            {
              name: "Some Task2",
              taskId: 20
            }
       ]
    },
    error: null
}

Mapping for (B)

RKObjectMapping* taskMapping = [RKObjectMapping mappingForClass:[Task class]];
    [taskMapping mapKeyPath:@"name" toAttribute:@"name"];
    [taskMapping mapKeyPath:@"taskId" toAttribute:@"taskId"];
    [objectManager.mappingProvider setMapping:taskMapping forKeyPath:@"tasks"]; 

RKObjectMapping* resultMapping = [RKObjectMapping mappingForClass:[Result class]];
    [resultMapping mapKeyPath:@"name" toAttribute:@"name"];
    [resultMapping mapRelationship:@"tasks" withMapping:taskMapping];
    [objectManager.mappingProvider setMapping:resultMapping forKeyPath:@"result"];

RKObjectMapping* cmplxMapng = [RKObjectMapping mappingForClass:[WsReturn class]];
    [cmplxMapng mapKeyPath:@"status" toAttribute:@"status"];
    [cmplxMapng mapKeyPath:@"error" toAttribute:@"error"];
    [cmplxMapng mapRelationship:@"result" withMapping:resultMapping];
    [objectManager.mappingProvider setMapping:cmplxMapng forKeyPath:@"/"];

Questions

1) (A) works alright. (B) does not. Can you provide some pointers?

2) For the same webservice call, "result" part could be a string (null) or a complex object. So how do I handle this in code? Which mapping do I pass? mapping or cmplxMapng (name changed to avoid horozontal scroll)?

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/myUrl"
objectMapping:HOW_TO_DECIDE_WHICH_MAPPING_TO_PASS_HERE delegate:self];

I believe this is a common scenario. I searched, but couldn't find related examples. Maybe I looked in the wrong places. Thoughts/pointers on how to approach this will help. Thanks.

Upvotes: 3

Views: 2044

Answers (1)

Ravi
Ravi

Reputation: 4009

So this is how I solved it -

1) I replaced this line:

[objectManager.mappingProvider setMapping:taskMapping forKeyPath:@"tasks"];    

with this: (notice forKeyPath)

[objectManager.mappingProvider setMapping:uooMapping forKeyPath:@"result.tasks"]; 

2) Followed this thread http://groups.google.com/group/restkit/browse_thread/thread/89b25b3f0f7e0177 & added this line as suggested by Blake:

[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.3]]; 

just before call to loadObjectsAtResourcePath

3) As for mapping the objects in different ways, I found that passing cmplxMapng always seems to work.

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/myUrl"     
                                 objectMapping:cmplxMapng delegate:self];

So if the "result" part comes back as the string "null", I get "(null)" for result & "status" & "error" fields are mapped correctly. Works!

Hope this helps someone.

Upvotes: 5

Related Questions