Reputation: 4009
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
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