Mapping a JSON response to an object using RestKit and Objective-C
Asked Answered
A

2

0

I am relatively new to Objective-C and am attempting to use RestKit to receive a JSON response from a web service. I have successfully received the data back to my application, which looks like this viewing the response:

{id:"1","Translation":"Test"}

I would like to map this translation to my "Translation" object in my application, but have tried a few different ways but am not sure how to achieve this.

So my questions are:

  1. How can I map this response to my Translation object
  2. Am I doing this correctly, creating a method to complete this call outwit my view controller?

My Translation Object

@implementation Translation  

@synthesize identifier = _identifier;
@synthesize translation = _translation;

- (NSDictionary*)elementToPropertyMappings {  
return [NSDictionary dictionaryWithKeysAndObjects:  
        @"id", @"identifier",  
        @"translation", @"translation",
        nil];  
}  

@end

My Translate Method

- (NSString *)performTranslation:(NSString *)translation
{

NSString *data = [[NSString alloc] initWithFormat:@"{\"SourceId\": \"%@\",\"RegionTag\": \"%@\",\"InputString\": \"%@\"}", @"1", @"Glasgow", translation];
NSString *post = data;

RKRequest *MyRequest = [[RKRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"http://my.url.com/Translation/Translate"]];
MyRequest.method = RKRequestMethodPOST;
MyRequest.HTTPBodyString = post;
MyRequest.additionalHTTPHeaders = [[NSDictionary alloc] initWithObjectsAndKeys:@"application/json", @"Content-Type", @"application/json", @"Accept", nil];
[MyRequest send];

RKResponse *Response = [MyRequest sendSynchronously];

return Response.bodyAsString; <--- looking to map this to translation object here

}
Audrit answered 29/11, 2011 at 10:52 Comment(0)
P
4

The snippet of your code seems a bit outdated. I strongly recommend reading the newest Object Mapping guide in order to leverage RestKit into it's fullest potential - especially the part Mapping without KVC.

Edit:

In order to post an object with RestKit and receive back an answer, we define a TranslationRequest class that will hold our request & Translation to hold our response.

Firstly, we set up our RKObjectManager and mappings (i usually do this in my AppDelegate):

RKObjectManager *manager = [RKObjectManager objectManagerWithBaseURL:kOurBaseUrl];
[manager setSerializationMIMEType:RKMIMETypeJSON];
//this is a singleton, but we keep the manager variable to avoid using [RKObjectManager sharedManager] all the time

//Here we define a mapping for the request. Note: We define it as a mapping from JSON to entity and use inverseMapping selector later.
RKObjectMapping *translationRequestMapping = [RKObjectMapping mappingForClass:[TranslationRequest class]];
[translationRequestMapping mapKeyPath:@"RegionTag" toAttribute:@"regionTag"];
...
[[manager mappingProvider] setSerializationMapping:[translationRequestMapping inverseMapping] forClass:[TranslationRequest class]];

//now we define the mapping for our response object
RKObjectMapping *translationMapping = [RKObjectMapping mappingForClass:[Translation class]];
[translationMapping mapKeyPath:@"id" toAttribute:@"identifier"];
[translationMapping mapKeyPath:@"Translation" toAttribute:@"translation"];
[[manager mappingProvider] addObjectMapping:mapping];

//finally, we route our TranslationRequest class to a given endpoint
[[manager router] routeClass:[TranslationRequest class] toResourcePath:kMyPostEndpoint];

This should be enough of the necessary setup. We can call our backend anywhere in the code (e.g. in any controller) like this:

//we create new TranslationRequest
TranslationRequest *request = [[TranslationRequest alloc] init];
[request setRegionTag:@"Hello"];
....
//then we fetch the desired mapping to map our response with
RKObjectMapping *responseMapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:class]
//and just call it. Be sure to let 'self' implement the required RKObjectManagerDelegate protocol
[[RKObjectManager sharedManager] postObject:request mapResponseWith:responseMapping delegate:self];]

Try this approach and let me know if you need any assistance.. I was not able to test it fully as i don't have any suitable backend that will return the responses, but judging from the RestKit log this should work.

Pleiades answered 29/11, 2011 at 11:41 Comment(8)
Many thanks for your response. Are you able to give me some assistance with an example? I am relatively new to Objective-C and, although I have read this, I haven't been able to find something which will allow me to post JSON to the server, which is required to retrieve my response.Audrit
Sure. What do you need to post to your server? Maybe this answer will help you a bit (describes how to post an array) #7726937 -- if not, feel free to get in touch with me.Pleiades
Thanks. I think I understand your example. My issue is 1) how to format my data for post - the format must be as above as the service can't be changed. 2) how to post to the service (there seem to be many different ways) and receive the response 3) how to map the response to a custom object. I think the docs I've been following are slightly outdated, which has confused me slightly. If you're able to provide an example with context, I'd really appreciate it.Audrit
just to be sure. The object (the JSON representation in your question) you send is the same you want to receive back from the server?Pleiades
sorry, ignore my comment. I see you want to post a different object - the one you construct as string.Pleiades
I need to post SourceId, RegionTag, InputString fields as JSON and the service returns {"id":"1","Translation":"Test"}, which I'd like to use as a Translation object in my project (detailed in the question). I hope this helps!Audrit
Thanks so much for the response. This really helps me understand it. So I have to create a new class for my previously undefined input, add the code provided to the delegate and call the back end using the code you've provided. This probably seems ridiculously simple, but how do I address the object's properties? Thanks again for all the effort you've put in to this answer.Audrit
let us continue this discussion in chatPleiades
E
3

You need to pass the returned JSON string into a JSON parser. I use SBJSON. You can then use the resulting dictionary to populate the properties of your object.

RestKit seems to have native objects that encapsulate four different JSON parsers. However, I'd advise caution because they seem to assume that the top level parsed object will always be a dictionary.

As another aside, the example in your question is not valid JSON. It should look like this:

{"id":"1","Translation":"Test"}
Essentiality answered 29/11, 2011 at 11:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.