Understanding Json and NSData - objective-c

We have to create a Jason file to send to server .
The way i found to do that is this :
NSDictionary* dic = #{#"Username" :userName,
#"Firstname" :firstName,
#"Lastname" : lastName,
#"Email" : email,
#"Password" : pass,
};
NSData* json = [NSJSONSerialization dataWithJSONObject:dic options:0 error:nil];
I dont really understand why after creating the dic , which is already a Json file, I have to use the NSJSONSerialization when creating the NSData ? ,why not just set the dic to the NSData ? What exactly this serialization do ?
Also ,why don't create just an NSString that will contain this structure ?

dic is an Objective-C dictionary (a collection of key-value pairs) and has nothing to do with JSON. Printing the dictionary might look similar to JSON, but it isn't.
NSJSONSerialization creates JSON data from the dictionary. JSON is a text format and is documented e.g. here: http://www.json.org. The JSON data for your dictionary would look like this:
{"Firstname":"John","Email":"jon#apple.com","Username":"john","Lastname":"Doe","Password":"topsecret"}
That NSJSONSerialization creates NSData and not NSString is just a design decision of the author of that class. You can convert the data to a string with
NSString *jsonString = [[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding];

Related

Objective C - how to Json Parse a dictionary having many dictionaries inside it?

Here is the main dictionary - 'query'.
I want to access 'results'- It is a NSDictionary having some key - pair values.
But, all the elements of 'query' dictionary (i.e count, results, created, lang, diagnostics) are inside 'query' dictionary's 0th element.
This is what I have written to access 'results'.
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"restuarant" ofType:#"json"]];
//query is main NSDictionary
self.query = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
//results is an NSDictionary
self.results = [_query valueForKey:#"results"][0];
But, when I debug it, everything is getting saved in 'query' variable but nothing is getting stored in 'results' variable.
I also tried the following code, but that didn't work out as well -
self.results = [_query valueForKey:#"results"];
I have looked upon many other stackoverflow pages, but none of them suit my needs. Regards.
From what I understand, it should be something like:
//results is an NSDictionary
self.results = [[_query valueForKey:#"query"] valueForKey:#"results"];
To debug it easier and to understand better the structure, you can also break the access to the results dictionary, into multiple steps, like:
NSDictionary *queryDictionary = [_query valueForKey:#"query"];
self.results = [queryDictionary valueForKey:#"results"];
then you can check what you have in the first dictionary and then in the second one.
Hope this helps!

How to send JSON-data in post request Objective-C?

I get an error while I send Json data to server. I used the following code to change the NSMutableDictionary To JSON.
NSString* jsonString1 = [postDict JSONRepresentation];
NSLog(#"%#",jsonString1);
JSON Format:
{"user_email":"gupta.nivrit#gmail.com","firstname":"nivrit","user_password":"1234","confirm_passward":"1234"}
I use the following method to send this JSON format to server:
NSMutableDictionary *responseDict =
(NSMutableDictionary *)[[mWebServiceHelperOBJ
makeCallToURL:#"register.php"
withDataPost:jsonString1] JSONValue];
When I implemented this code I received this issue
incompatible pointer type sending NSString to parameter of type NSMutableDictionary.
If your method
- (NSString *)makeCallToURL:(NSString*)url withDataPost:(NSMutableDictionary*)dict;
is the same as in this question: Uploading PDF file through JSON Web Service, then the JSON encoding of the request data is done inside
that method, so you should call it directly with the postDict,
and not with the JSON string jsonString1:
NSMutableDictionary *responseDict =
(NSMutableDictionary *)[[mWebServiceHelperOBJ makeCallToURL:#"register.php"
withDataPost:postDict] JSONValue];
(This assumes that postDict is an NSMutableDictionary.)

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: NSString not being entirely decoded from UTF-8

I'm querying a web server which returns a JSON string as NSData. The string is in UTF-8 format so it is converted to an NSString like this.
NSString *receivedString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
However, some UTF-8 escapes remain in the outputted JSON string which causes my app to behave erratically. Things like \u2019 remain in the string. I've tried everything to remove them and replace them with their actual characters.
The only thing I can think of is to replace the occurances of UTF-8 escapes with their characters manually, but this is a lot of work if there's a quicker way!
Here's an example of an incorrectly parsed string:
{"title":"The Concept, Framed, The Enquiry, Delilah\u2019s Number 10 ","url":"http://livebrum.co.uk/2012/05/31/the-concept-framed-the-enquiry-delilah\u2019s-number-10","date_range":"31 May 2012","description":"","venue":{"title":"O2 Academy 3 ","url":"http://livebrum.co.uk/venues/o2-academy-3"}
As you can see, the URL hasn't been completely converted.
Thanks,
The \u2019 syntax isn't part of UTF-8 encoding, it's a piece of JSON-specific syntax. NSString parses UTF-8, not JSON, so doesn't understand it.
You should use NSJSONSerialization to parse the JSON then pull the string you want from the output of that.
So, for example:
NSError *error = nil;
id rootObject = [NSJSONSerialization
JSONObjectWithData:receivedData
options:0
error:&error];
if(error)
{
// error path here
}
// really you'd validate this properly, but this is just
// an example so I'm going to assume:
//
// (1) the root object is a dictionary;
// (2) it has a string in it named 'url'
//
// (technically this code will work not matter what the type
// of the url object as written, but if you carry forward assuming
// a string then you could be in trouble)
NSDictionary *rootDictionary = rootObject;
NSString *url = [rootDictionary objectForKey:#"url"];
NSLog(#"URL was: %#", url);

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