how to parse this JSON in OBJ c - objective-c

I receive this JSON string from a web process
{
"result":"ok",
"description":"",
"err_data":"",
"data":[
{
"id":"14D19A9B-3D65-4FE2-9ACE-4C2D708DAAD8"
},
{
"id":"8BFD10B8-F5FD-4CEE-A307-FE4382A0A7FD"
}
]
}
and when I use the following to get the data:
NSError *jsonError = nil;
NSData *objectData = [ret dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json= [NSJSONSerialization JSONObjectWithData: objectData options:kNilOptions error: &jsonError];
NSLog(#"data: %#",[json objectForKey:#"data"]);
it gets logged as:
(
{
id = "14D19A9B-3D65-4FE2-9ACE-4C2D708DAAD8";
},
{
id = "8BFD10B8-F5FD-4CEE-A307-FE4382A0A7FD";
}
)
How can I parse the data as an NSDictionary with value and keys?

The web returns an object that has a property which is an array of objects, so...
NSDictionary *json= // your code
NSArray *array = json[#"data"];
for (NSDictionary *element in array) {
NSLog(#"%#", element);
// or, digging a little deeper
NSString *idString = element[#"id"];
NSLog(#"id=%#", idString);
}

Related

JSON Parsing Error (blank response)

Here's my code, when I run it, I get: "2014-10-26 19:02:09.153 App[27372:1281902] Price: (
)".
I was wondering why, no errors are being passed through and it honestly confuses me.
(I'm getting a blank response for "omc_usd_price")
#try
{
NSURL *url = [NSURL URLWithString:#"https://omnicha.in/api?method=getinfo"];
NSData *data=[NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableDictionary *JSONStuff= [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error: &error];
NSLog(#"%#",JSONStuff);
NSMutableArray * OMCArray = [[NSMutableArray alloc]init];
NSArray * responseArr = JSONStuff[#"omc_usd_price"];
for(NSDictionary * dict in responseArr)
{
[OMCArray addObject:[dict valueForKey:#"omc_usd_price"]];
}
NSLog(#"Price: %# test", OMCArray); // Here you get the Referance data
}
#catch (NSException *exception) {
NSLog(#"%#", exception);
}
#finally {
}
EDIT:
Tried this, I don't think I did this right either!
NSMutableArray * OMCArray = [[NSMutableArray alloc]init];
NSMutableArray * OMCArray2 = [[NSMutableArray alloc]init];
NSArray * responseArr = JSONStuff[#"response"];
NSArray * responseArr2 = JSONStuff[#"omc_usd_price"];
for(NSDictionary * dict in responseArr)
{
[OMCArray addObject:[dict valueForKey:#"response"]];
for(NSDictionary * dict2 in responseArr2)
{
[OMCArray addObject:[dict2 valueForKey:#"omc_usd_price"]];
}
}
NSLog(#"Price: %# test", OMCArray2); // Here you get the Referance data
Here is the JSONStuff dictionary:
{
"error":false,
"response":{
"block_count":96136,
"difficulty":12.18364177,
"netmhps":234.652099,
"seconds_since_block":694,
"avg_block_time":196.533,
"total_mined_omc":6426691.6,
"omc_btc_price":7.0e-6,
"omc_usd_price":0.0025,
"market_cap":15833.5909
}
}
As you can see, there is no entry in the dictionary named "omc_usd_price". There is a entry by that name in the dictionary name "response", but you didn't ask for that.
If you want to get omc_usd_price, as mentioned on your code, then you need to parse 2 dictionaries.
You must first parse the dictionary with the key response, and this will give you a new dictionary.
Then in this new dictionary you must parse/look for the key omc_usd_price.
Also, you're not getting an array back, but a double or float or even a string.

How to iterate through a simple JSON object in Objective-C?

I'm very new to Objective-C, I'm a hardcore Java and Python veteran.
I've created an Objective-C script that calls a URL and gets the JSON object returned by the URL:
// Prepare the link that is going to be used on the GET request
NSURL * url = [[NSURL alloc] initWithString:#"http://domfa.de/google_nice/-122x1561692/37x4451198/"];
// Prepare the request object
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:30];
// Prepare the variables for the JSON response
NSData *urlData;
NSURLResponse *response;
NSError *error;
// Make synchronous request
urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
// Construct a Array around the Data from the response
NSArray* object = [NSJSONSerialization
JSONObjectWithData:urlData
options:0
error:&error];
//NSLog(object);
// Iterate through the object and print desired results
I've gotten this far:
NSString* myString = [#([object count]) stringValue];
NSLog(myString);
Which returns the size of this array, but how can I loop through this JSON object and print each element?
Here's the JSON I'm loading:
{
"country": "United States",
"sublocality_level_1": "",
"neighborhood": "University South",
"administrative_area_level_2": "Santa Clara County",
"administrative_area_level_1": "California",
"locality": "City of Palo Alto",
"administrative_area_level_3": "",
"sublocality_level_2": "",
"sublocality_level_3": "",
"sublocality":""
}
The top-level object your JSON object is a dictionary, not an array, as indicated by the curly braces. If you are not sure whether you are going to get an array or a dictionary back, you can do some safety checking like this:
// Construct a collection object around the Data from the response
id collection = [NSJSONSerialization JSONObjectWithData:urlData
options:0
error:&error];
if ( collection ) {
if ( [collection isKindOfClass:[NSDictionary class]] ) {
// do dictionary things
for ( NSString *key in [collection allKeys] ) {
NSLog(#"%#: %#", key, collection[key]);
}
}
else if ( [collection isKindOfClass:[NSArray class]] ) {
// do array things
for ( id object in collection ) {
NSLog(#"%#", object);
}
}
}
else {
NSLog(#"Error serializing JSON: %#", error);
}
Well for starters, the JSON you linked to is not an array, it is a dictionary.
NSDictionary* object = [NSJSONSerialization
JSONObjectWithData:urlData
options:0
error:&error];
There are a number of ways to iterate through all of the keys/values, and here is one:
for(NSString *key in [object allKeys])
{
NSString *value = object[key]; // assuming the value is indeed a string
}

Manipulating Facebook/JSON data

I'm trying to handle Facebook JSON data and transform it into a NSMutable Dictionary, but I'm getting (null) when I try to print the data. Although when I try to do a count, I get a number.
User_likes is NSMutableDictionary which is globally defined. I'm getting (null) on this line:
NSLog(#"User likes: %#", user_likes);
This is my code:
NSString *query =
#"SELECT page_id, type FROM page_fan WHERE uid = me() ";
// Set up the query parameter
NSDictionary *queryParam = #{ #"q": query };
// Make the API request that uses FQL
[FBRequestConnection startWithGraphPath:#"/fql"
parameters:queryParam
HTTPMethod:#"GET"
completionHandler:^(FBRequestConnection *connection,
id results,
NSError *error) {
if (error) {
NSLog(#"Error: %#", [error localizedDescription]);
} else {
user_likes = [NSJSONSerialization JSONObjectWithData:results options:kNilOptions error:&error];
NSLog(#"User likes: %#", user_likes);
NSInteger* n_user_likes = [results count];
NSInteger* n_user_likes2 = [user_likes count];
NSLog(#"n user likes %qi", n_user_likes);
NSLog(#"n user likes2 %qi", n_user_likes2);
id val = nil;
id values = [[user_likes allKeys] objectAtIndex:0 ];
NSLog(#"values id %#", values);
When I print results, I get a lot of data from Facebook, this is a sample of it:
data = (
{
"page_id" = 253370381511811;
type = "PUBLIC FIGURE";
},
{
"page_id" = 148389618201;
type = "LOCAL BUSINESS";
},
{
"page_id" = 213631462169238;
type = COMMUNITY;
},
{
"page_id" = 162297750451425;
type = "NON-PROFIT ORGANIZATION";
},
{
"page_id" = 503620106320217;
type = "MEDIA/NEWS/PUBLISHING";
},
you can't do directly
user_likes = [NSJSONSerialization JSONObjectWithData:results options:kNilOptions error:&error];
you need first create a dictionary with the data in results like this:
NSDictionary *dictionary = [NSDictionary dictionaryWithJSONData:results];
user_likes = [NSString stringWithFormat:#"%d",[[dictionary objectForKey:#"value_of_the_likes"] intValue]];
NSLog(#"%#",user_likes);
NSLog(#"%#",dictionary);
EDIT:
Please, create this class to your project and import in the class where you need use this.
#import <Foundation/Foundation.h>
#interface NSDictionary (JSONExtensions)
+(NSDictionary*)dictionaryWithJSONData:(NSData*)data;
-(NSData*)JSONValue;
-(NSString*)JSONString;
#end
#implementation NSDictionary(JSONExtensions)
+(NSDictionary*)dictionaryWithJSONData:(NSData*)data{
NSError *error = nil;
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if(error){
NSLog(#"%#",error);
return nil;
};
return result;
}
-(NSData*)JSONValue{
NSError *error = nil;
NSData *result = [NSJSONSerialization dataWithJSONObject:self options:kNilOptions error:&error];
if(error){
NSLog(#"%#",error);
return nil;
};
return result;
}
-(NSString*)JSONString{
return [[NSString alloc] initWithData:self.JSONValue encoding:NSUTF8StringEncoding];
}
#end
Hope it can help you.
maybe you forget set up options:
NSJSONReadingOptions options = NSJSONReadingAllowFragments | NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves;
user_likes = [NSJSONSerialization JSONObjectWithData:results options:options error:&error];
i hope this be useful for you!
UPDATE:
Check this :
NSJsonSerialzation not parsing results from Facebook - Cocoa error 3840
Let me know if that helps you!

Parsing JSON: Checking for object existence and reading values

My application returns a NSMutableData *receivedData.
I've opted for using NSJSONSerialization to parse this under the assumption that it would be easiest. I'm having extreme trouble trying to get my head around how to do it. I'm very new to Objective-C, from a Java background.
In Java I used gson to parse the JSON in to an array which I could use easily. I'm really struggling with this here.
My current code for parsing the JSON is:
NSError *e = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData: receivedData options: NSJSONReadingMutableContainers error: &e];
if (!jsonArray) {
NSLog(#"Error parsing JSON: %#", e);
} else {
for(NSDictionary *item in jsonArray) {
NSLog(#"Item: %#", item);
}
}
As provided by somebody on the internet. This works and prints two items to NSLog. result and header. Here is how the JSON looks:
{
"header":{
"session":"sessionid",
"serviceVersion":"1",
"prefetchEnabled":true
},
"result":"50ce82401e826"
}
However if there is an error the JSON can also look like this:
{
"header":{
"session":"sessionid",
"serviceVersion":"1",
"prefetchEnabled":true
},
"fault":{
"code":0,
"message":"someErrorCode"
}
}
How I want the code to work:
Check if there is a "fault" object
If there is, print fault.code and fault.message to NSLog
If there isn't, I know that my JSON contains result instead of fault
Print the value of result to NSLog
But I can't for the life of me figure out how to approach it. Can someone please give me some pointers?
your object appears to be a dictionary.
Try this out.
NSError *e = nil;
id jsonObj = [NSJSONSerialization JSONObjectWithData: receivedData options: NSJSONReadingMutableContainers error: &e];
NSArray *jsonArray = nil;
NSDictionary *jsonDict = nil;
if ([jsonObj isKindOfClass:[NSArray class]]){
jsonArray = (NSArray*)jsonObj;
}
else if ([jsonObj isKindOfClass:[NSDictionary class]]){
jsonDict = (NSDictionary*)jsonObj;
}
if (jsonArray != nil) {
// you have an array;
for(NSDictionary *item in jsonArray) {
NSLog(#"Item: %#", item);
}
}
else if (jsonDict != nil){
for (NSString *key in jsonDict.allKeys){
NSLog(#"Key: %# forItem: %#",key,[jsonDict valueForKey:key]);
}
}
else {
NSLog(#"Error: %#",e);
}

NSJSONSerialization only getting root key

I'm having an issue parsing JSON from a PHP server using NSJSONSerialization. JSLint says my JSON is valid but appears to only be able to get one-two levels in.
This is essentially my JSON structure:
{
"products":
[{
"product-name":
{
"product-sets":
[{
"set-3":
{
"test1":"test2",
"test3":"test4"
},
"set-4":
{
"test5":"test6",
"test7":"test8"
}
}]
},
"product-name-2":
{
"product-sets":
[{
}]
}
}]
}
and here is my code to parse it:
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
if (json) {
NSArray *products = [json objectForKey:#"products"]; // works
for (NSDictionary *pItem in products) { // works
NSLog(#"Product: %#", pItem); // works, prints the entire structure under "product-name"
NSArray *productSets = [pItem objectForKey:#"product-sets"]; // gets nil
for (NSDictionary *psItem in productSets) {
// never happens
}
}
}
I've been spinning my wheels on this for several hours, but I'm not finding anything similar anywhere I search. Are there any limitations that I'm unaware of, or am I just not seeing something obvious?
you missed one nested object
NSArray *productSets = [[pItem objectForKey:#"product-name"] objectForKey:#"product-sets"];
I tested it with this CLI program
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSString *jsonString = #"{\"products\":[{\"product-name\": {\"product-sets\": {\"set-3\":{\"test1\":\"test2\", \"test3\":\"test4\"}, \"set-4\":{\"test5\":\"test6\", \"test7\":\"test8\"} }}}, {\"product-name-2\": \"2\"}]}";
// insert code here...
NSLog(#"%#", jsonString);
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
if (json) {
NSArray *products = [json objectForKey:#"products"]; // works
for (NSDictionary *pItem in products) { // works
NSLog(#"Product: %#", pItem); // works, prints the entire structure under "product-name"
NSArray *productSets = [[pItem objectForKey:#"product-name"] objectForKey:#"product-sets"]; // gets nil
for (NSDictionary *psItem in productSets) {
NSLog(#"%#", psItem);
}
}
}
}
return 0;
}
Note, that some things in your json are quite strange:
for each flattened object the keys should be the same. keys, that include a number o an object do not make much sense. If you need to keep track of single objects, include an id key with a proper value.