How do I create Json requests in Objective C - objective-c

I have a great framework however I cannot figure out how to create requests. All the tutorials assume you are simply downloading and parsing Json data - but I need to build a Json request send it off and then parse the response.
Anyone have ideas and in particular sample code which builds up the request.

The framework doesn't handle NSObject but NSDictionary seems to work:
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
#"value1", #"key1", #"value2", #"key2", nil];
NSString *requestJson = [jsonDictionary JSONRepresentation];
NSLog(#"requestJson %#", requestJson);

In this JSON framework...you can use the JSONRepresentation method on NSDictionary and NSArray.....

You should download JSON lib, then import header:
#import "NSObject+SBJSON.h"

Related

JSON format issue

I am new to web services and have GET working fine. When I try to POST I am sending this JSON string:
{"frequency":"None","leader":"test#test.com"}
But the server is expecting this:
{
"meta":
{"limit": 20, "total_count": 2},
"objects":
[{"frequency": "None", "leader": "jsmith#gmail.com"},
{"frequency": "None", "leader": "jsmith#gmail.com"}]
}
In my NewMeetingRK object I am trying to map to the "objects" as follows:
mgr.serializationMIMEType = RKMIMETypeJSON;
RKObjectMapping* newmtg = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[newmtg mapKeyPath: #"frequency" toAttribute:#"repeat" ];
[newmtg mapKeyPath: #"leader" toAttribute:#"leader" ];
RKObjectMapping* newmtgSerializeMapping = [newmtg inverseMapping];
[mgr.mappingProvider setSerializationMapping:newmtgSerializeMapping forClass:[NewMeetingRK class]];
[mgr.mappingProvider setMapping:newmtgSerializeMapping forKeyPath:#"objects"];
[mgr.router routeClass:[NewMeetingRK class] toResourcePath:#"" forMethod:RKRequestMethodPOST];
This isn't working. I tried changing toResourcePath to #"/objects" but that didn't work either. Any idea how to send the values to the second set of JSON values on the server?
---EDIT----
I was missing the array as #HotLicks pointed out - thanks. But I still can't get my simple post with JSON values to work.
Instead of RKObjectManager can I do something simple with RKClient like this?
client = [RKClient clientWithBaseURL:[RKURL URLWithBaseURLString:#"https://appzute.appspot.com"]];
NSLog(#"I am your RKClient singleton : %#", [RKClient sharedClient]);
client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
[client setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSMutableArray *meetingArray = [NSMutableArray arrayWithCapacity:100];
[meetingArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
self.leaderEmail.text, #"leader",
self.repeatLabel.text, #"frequency",
nil]];
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjectsAndKeys:meetingArray, #"objects", nil];
NSString *jsonString = [jsonDictionary JSONRepresentation];
NSLog (#"jsonString is: %#",jsonString);
[client post:#"/api/meeting/?format=json&username=testuser#test.com&api_key=sdf7asd87fs8df78sdf" params:jsonString delegate:self];
The value of jsonString looks perfect: {"objects":[{"leader":"me#me.com","frequency":"None"}]}
The issue is that params:jsonString is not valid, because it needs an object not a string. But if I use params: jsonDictionary then I get this log file:
Sent RKRequest: objects[][leader]=me%40me.com&objects[][frequency]=None
I restkit.network:RKRequest.m:676 Status Code: 500
What could I possibly be doing wrong?
Thanks!
Unfamiliar with that JSON toolkit, but generally what you'd do is create two dictionaries, one for each of your "objects", place them in an array (your "objects" array). Then create a dictionary for your "meta" info. Finally, create a dictionary to contain the "meta" info and the "objects" array.
JSON maps almost perfectly to NSDictionary/NSArray, so there's not really any need to use a toolkit that uses "wrapper" objects.

Objective C, NSDictionary loop through each object

I am new to Facebook Developer. I want to create Mac OSX application using Facebook API. When i request FQL and its return me JSON data only like below:
My Code:
[self.result_text setString:[NSString stringWithFormat:#"%#",[result objectForKey: #"result"]];
It display:
[{"name":"My Name","first_name":"My First Name","last_name":"My Last Name"}]
I want to read the object inside this Dictionary. Example I just want to display "My Name" string. But I don't know how to it.
Thanks,
As Ashley Mills wrote, you should check the documentation. You can loop through the all dictionary keys like this:
for ( NSString *key in [dictionary allKeys]) {
//do what you want to do with items
NSLog(#"%#", [dictionary objectForKey:key]);
}
Hope it helps
You can parse the JSON contents from the server into a NSDictionary object via Lion's brand new NSJSONSerialization class (documentation linked for you).
e.g.
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData: [self.result_text dataUsingEncoding: NSUTF8StringEncoding] options: nil error: &error];
And once you have it in a NSDictionary object, it's easy to do something like:
NSString * myLastNameContent = [jsonDictionary objectForKey: #"last_name"];
Sergio's answer (which he keeps editing, even as I type :-) is very good too. +1 to him.
You can use JSONKit to transform the JSON string into a dictionary:
NSDictionary *resultsDictionary = [resultString
objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode|JKParseOptionValidFlags error:&err];
NSString* name = [resultDictionary objectForKey:#"name"];
JSONKit is straightforward to use and will make your application work also on older SDK versions.
You should read the documentation for NSDictionary here:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsdictionary_Class/Reference/Reference.html
in particular the section titled Accessing Keys and Values

How to specify tags when uploading video to Facebook using the Graph API

I'm able to upload videos to Facebook successfully using the latest Graph API via Objective-C. However, I'd like to also tag certain Facebook users who are in the video. I cannot get this to work.
The FB documentation says that there is a "tag" field that accepts an array of objects containing id and name fields. However, if I try to pass a JSON string in this format the video upload fails, without any useful error message. Am I passing the tags data correctly?
Here's sample code that fails. The code succeeds when I remove the #"tags" field from params, or set tagStr to an empty array, i.e. #"[]".
NSString *tagStr = #"[{\"id\":\"<id-removed>\", \"name\":\"<name-removed>\"}]";
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
data, #"video.mov",
#"video/quicktime", #"contentType",
titleStr, #"title",
descStr, #"description",
tagStr, #"tags", // specifying tags fails
nil];
[facebook requestWithGraphPath:#"me/videos"
andParams:params
andHttpMethod:#"POST"
andDelegate:self];
Your Params Dictionary Should be like this,
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
videoData, #"video.mov",
#"video/quicktime", #"contentType",
#"Birthday wishes", #"title",
#"via Birthday wishes", #"description",facebook.accessToken,#"access_token",
nil];
After the Video gets posted,you can able to tag friends in - (void)request:(FBRequest *)request didLoad:(id)result as like
[APP.facebook requestWithGraphPath:[NSString stringWithFormat:#"%#/tags/%#?access_token=%#", photoID, [ar_tID objectAtIndex:i], APP.facebook.accessToken]andParams:nilandHttpMethod:#"POST" andDelegate:self];

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

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:
How can I map this response to my Translation object
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
}
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.
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"}

parsing JSON using objective C?

I have spent 1 week studying objective C. Now I am quite confused at the dealing with data part.
My friend gave me a link
http://nrj.playsoft.fr/v3/getQuiz.php?udid=23423455&app=2
and ask me write a class to parse this JSON. I had no clue what parsing JSON means. but I have gone online and looked up. I could understand a basics of it and then I impletemented a punch of code to parse this JSON. Which is:
-
(void)parseURL
{
//create new SBJSON object
SBJSON *parser = [[SBJSON alloc] init];
NSError *error = nil;
//perform request from URL
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://nrj.playsoft.fr/v3/getQuiz.php?udid=23423455&app=2"]];
// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
// Get JSON as a NSString from NSData response
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
// parse the JSON response into an object
NSDictionary *results = [parser objectWithString:json_string error:&error];
// array just for the "answer" results
NSArray *quizes = [results objectForKey:#"quiz"];
NSDictionary *firstQuiz = [quizes objectAtIndex:0];
// finally, the name key
NSString *extract = [firstQuiz objectForKey:#"extract"];
NSLog(#"this is: %#", [extract valueForKey:#"extract"]);
}
This is at the implementation file, but in the header file I could not declare any variables, it will print out some errors. I tried to run this, there is no errors, but I am not sure this code is correct or not. And my friend asked me to write a class into an existing project. I don't know what needs to be modified and what not. I am so blur right now. Could anyone pro in this give me a hand. ?
My sincere thanks.
Thanks for reply. I have downloading and added the JSON framework ealier too. I am just not sure where to begin and where to end, meaning the step I should do when I add JSON framework into it. I could understand the syntax but I am not sure about the steps I should do. I am a newbie in this.
If you support iOS 5.0+, you should use built-in NSJSONSerialization.
It is faster than TouchJSON.
You could just use TouchJSON: http://code.google.com/p/touchcode/wiki/TouchJSON
Or you could use this one: http://code.google.com/p/json-framework/
I'm sure there are others. I use TouchJSON... it's fast and has a good API.
I recommend working through Ray Wenderlich's MapKit tutorial, especially if you are a newbie. It covers several common iOS development issues, including parsing JSON data.
http://www.raywenderlich.com/2847/introduction-to-mapkit-on-ios-tutorial
"The Implementation" section is where his JSON feed is retrieved and then in "Plotting the Data" he uses the SBJson library to parse it.