Cocoa Touch JSON Handling - objective-c

I've been looking for a while now and I can't seem to find a solution.
I am trying to format a JSON object that is being held in an NSData *receivedData.
The format of the JSON is:
[
{
"name":"Stephen",
"nickname":"Bob"
},
{
"name":"Rob",
"nickname":"Mike"
},
{
"name":"Arya",
"nickname":"Jane"
}
]
Normally I would use "NSJSONSerialization JSONObjectWithData:" of the NSDictionary. Then I would normally take the root of the JSON (in this case it would be something like "People":) and create the array from that root object. However as you can see this response is simply an array without a root object. I'm not sure how to handle this. The end goal is to have an array of Person objects, populated with the data in the JSON.
Edit: I would also like to add that I want to keep it native without third party libraries.

OK for anyone reading this. I just figured it out. Instead of formatting the initial NSData into a dictionary, you put that straight into an array. Then create a dictionary for each object in the array. Like so:
NSArray *response = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSDictionary* json = [responseArray objectAtIndex:0];
NSLog (#"%#",[json objectForKey:#"nickname"]);

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 handle JSON exception objective c

Before I make url, which I will use to fetch json, user has to input some data first.
If the input data is wrong, the JSON will not be fetched properly.
But I cannot figure out how to handle that exception of calling JSON with wrong url.
this is my code:
NSError *error;
NSMutableDictionary* json = [NSJSONSerialization
JSONObjectWithData:url
options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves
error:&error];
if (error){
NSLog(#"%#",[error localizedDescription]);
}
else{
#try {
if (json){
[Constants shared].salt = json[#"salt"];
The last line of code is where the exception occurs, since the user had put the wrong input.
SO obviously, there wont be a proper json response fetchet, and there will be no "salt" object.
Error I get is:
-[__NSArrayM objectForKeyedSubscript:]: unrecognized selector sent to instance 0x146aa310
I tried putting json fetching in #try #catch, but it didn't work out.
Any suggestions ?
EDIT:
this is the json responce I get, when the user types in the right code:
{
user_id: "22066",
salt: "ce8c0f9e3e1add06bebc1acded7b692b68efddb87bfdc5bb1fb516f6a3e24425"
}
This is what i get, when the code is invalid:
[ ] (empty array)
The problem isn't that the dictionary lacks an object for the key #"salt", it's that json isn't a dictionary in the first place. Take a close look at the error message and you'll see that it's an array. The problem isn't the key, but the fact that arrays don't respond to -objectForKeyedSubscript:.
Accordingly, when you get an object back from -JSONObjectWithData:..., check that it's not nil and that it is in fact a dictionary before you try to access its contents. You can check it like this:
if ([json isKindOfClass:[NSDictionary class]]) {
// put the code that accesses `json` here
}
That condition will be false if json is nil or something other than a dictionary. You could add an else clause to take any necessary steps to recover if you're relying on getting the data.

retrieving certain keys from a returned JSON in Objective C

I am sending a JSON encoded POST type to a server of mine which reads the sent information in PHP and decodes it there. Now when I re-encode it and send it back it works perfectly and I can NSLog the response but my issue is how do I get a specific section of the response?
Here is an example response:
responseString: {"status":"ok","code":0,"original request":{"username":"test"
`,"password":"test"}}`
Suggestions, thoughts?
What you are receiving is actually a 'dictionary of objects'. You can separate the data in the above code as follows:
First, serialize the response data using JSON serialization as follows:
NSError* error;
NSDictionary* responseDictionary = [NSJSONSerialization JSONObjectWithData:returnData options:nil error:&error];
You may then separate the dictionary as you wish.For instance, if you want to retrieve the value for "status", you may use:
NSString *status = [responseDictionary objectForKey:#"status"];
Or, if you want to retrieve "original request" which is another dictionary, you may use:
NSDictionary *originalRequest = [responseDictionary objectForKey:#"original request"];
Hope this helps!
The response received from the server is JSON data.
Here is an excellent tutorial on JSON parsing for iOS and there are plenty of tutorials & docs if you browse.
http://www.raywenderlich.com/5492/working-with-json-in-ios-5
In JSON, "{}" represents a dictionary and "[]" is an array. So, try this
NSDictionary* originalRequest = [responseString objectForKey:#"original request"];
you can dig in further like this,
NSString* username = [originalRequest objectForKey:#"username"];
I strongly recommend you to read some tutorials on JSON.

Parse JSON String and array with NSJSONSerialization issue?

This is the code i have so far
// Parse data using NSJSONSerialization
NSError *error = nil;
NSArray *JsonArray = [NSJSONSerialization JSONObjectWithData:myData options:NSJSONReadingMutableContainers error: &error];
if(!JsonArray)
{
NSLog(#"Error Parsing Data: %#", error);
}
else
{
for(NSDictionary *event in JsonArray)
{
if([[event description] isEqualToString:#"error"])
{
// Get error number? I am confused by this part
NSLog(#"Element: %#", [event objectForKey:#"error"]);
}
else
{
NSLog(#"Element: %#", [event description]);
}
}
}
this is the JSON Data that parses correctly:
[{data string}, {data strings}]
This only gives me the string "error" and not the int as well:
{"error":0}
I am echoing this data from a PHP script if that helps any. Am i just doing it wrong, or did i miss something?
Your problem is that when you receive an error, you get back an NSDictionary and not an NSArray. This should work:
if ([jsonObject isKindOfClass:[NSArray class]]) {
// no error: enumerate objects as you described above
} else if ([jsonObject isKindOfClass:[NSDictionary class]]) {
// error: obtain error code
NSNumber *errCode = jsonObject[#"error"];
} else {
// something bad's happening
}
Stylistic pieces of advice:
Don't call your object JsonArray, since it's not always an array. Call it jsonObject.
Don't start variable names with capital letters.
Would be great if you had posted the complete JSON document that you are trying to parse, because without that, there is absolutely no chance to figure out whether your code is anywhere near correct. The example [{data string}, {data strings}] that you gave is most definitely not a correct JSON document, so trying to parse it will return nil. {"error":0} is a dictionary with a single key "error" and a value 0. Having dictionaries with a single key is let's say unusual.
A JSON document contains either an array or object (using JSON terms) which will be turned either into an NSArray* or an NSDictionary*. You should know whether you expect an array or dictionary. If you expect an NSArray, check that [jsonObject isKindOfClass:[NSArray class]]. If you expect an NSDictionary, check that [jsonObject isKindOfClass:[NSDictionary class]]. If you don't do that then the wrong JSON document will either crash your app or produce total nonsense.
If you have an array then you will usually iterate through the elements of the array and handle each one in turn. If you have a dictionary you will usually look up keys that you know how to handle. What you are doing, iterating through an array of dictionaries, and checking for a dictionary with a key of "error", that's a very strange design of your JSON document.
And lookup what the "description" method does. "description" is what NSLog calls to find out what to print when it is asked to print an object. For an NSDictionary with a single key "error" and a value 0, it would return something like "error:0" which is of course not the same as "error".
NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:myData options:NSJSONReadingMutableContainers error:&error];
NSLog(#"jsonDic: %#", [jsonDic objectForKey:#"string"]);

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