unable to access JSON data in Objective-C - iphone

Ok, this is my first approach to JSONs in Objective-C (and i'm quite new to the last one too). i'm to get infos stored my json to use them in Objective-C, but when trying to load it i get null in response from NSLog(#"%#",allData); on. Can anybody please tell me what i am doing wrong? thanks in advance for your time and your patience.
oh and if needed here's the json:
http://jsonviewer.stack.hu/#http://conqui.it/ricette.json
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"recipes" ofType:#"json"];
NSError *error = nil;
NSMutableData *JSONData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&error];
NSLog(#"%#",JSONData);
NSArray *allData = [NSJSONSerialization JSONObjectWithData:JSONData options:0 error:nil];
NSLog(#"%#",allData);
for (NSDictionary *diction in allData) {
NSString *recipe = [diction objectForKey:#"recipe"];
[array addObject:recipe];
}
NSLog(#"%#",array);

The JSONObjectWithData method has an error parameter, of which you can avail yourself in order to diagnose the problem. For example:
NSError *error = nil;
NSArray *allData = [NSJSONSerialization JSONObjectWithData:JSONData
options:0
error:&error];
if (error)
NSLog(#"%s: JSONObjectWithData error: %#", __FUNCTION__, error);
In your comments, you suggest that you received an error about "Unescaped control character around character 414." That would suggest an error in the JSON, itself, which you might want to validate by copying into http://jsonlint.com/ and see if it reports any issues.
In response to the broader question about whether there are any Objective-C issues, there are no coding errors, per se. I can't comment on the for loop which clearly assumes that allData is an array of dictionaries to which I cannot attest without seeing the JSON. But I'll take your word for it. But, yes, the Objective-C code looks fine (albeit, a little light on checking of the return values types and error objects).
For example, if you wanted some diagnostic assert statements that you could use during development, you might do something like:
NSArray *allData = [NSJSONSerialization JSONObjectWithData:JSONData options:0 error:nil];
NSAssert(error, #"%s: JSONObjectWithData error: %#", __FUNCTION__, error);
NSLog(#"%s: array=%#", __FUNCTION__, array);
NSAssert([allData isKindOfClass:[NSArray class]], #"allData is not an array");
for (NSDictionary *diction in allData) {
NSAssert([diction isKindOfClass:[NSDictionary class]], #"%s: diction is not a dictionary (%#), __FUNCTION__, diction);
NSString *recipe = [diction objectForKey:#"recipe"];
NSAssert(recipe, #"%s: Did not find recipe key in diction (%#)", __FUNCTION__, diction);
[array addObject:recipe];
}
If any of these errors were possible runtime errors in production, you'd replace assert statements with if statements that do the necessary error handling. But hopefully it illustrates the concept.

Problem in your response is that , string values are unable to concatenate.So, I have to manually remove those tabs and new lines.
At five places you are getting error i.e:
pelate.
pasta.
pomodoro.
saporiti).
\t
- (void)viewDidLoad
{
NSString *urlStr=[NSString stringWithFormat:#"http://www.conqui.it/ricette.json"];
urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *fileNameURL=[NSURL URLWithString:urlStr];
NSLog(#"url is %#",urlStr);
NSMutableURLRequest *filenameReq=[[NSMutableURLRequest alloc] initWithURL:fileNameURL];
NSData *responseData=[NSURLConnection sendSynchronousRequest:filenameReq returningResponse:nil error:nil];
NSString *responseString=[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
responseString=[[responseString componentsSeparatedByString:#"\n"] componentsJoinedByString:#""];
responseString=[responseString stringByReplacingOccurrencesOfString:#"\t" withString:#""];
responseData=[responseString dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"response String is %#",responseString);
[NSCharacterSet characterSetWithCharactersInString:responseString];
NSError *e = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:responseData options: 0 error: &e];
NSLog(#"JSON Array is %# & error is %#",jsonArray,e);
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

Related

How do I extract a value from the following code?

How do I extract just the "token" value from the following code? I'm looking to save this value into a string.
Is meta an array? If so how would I extract the data from the "token" value?
thanks for any help
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
Response ==> {"meta":[],"data":{"token":"IVZ2ciRkbVtDLUl3YmhwOTkyXzpRR1M3LUUsRiElfWF6T3I6dCxsRWg6di1XcyR6OTUzZHhVazdLTEJ7blU5O258d2xRTXg0VUxwQXBlNHRSOXd2VXZ1aG1RfFhQQjJsSkkoc2IuOTFyYkYodyhAe2RldXR1aDF3RClXWyhoMiU="}}
2013-07-19 15:10:23.139 appName [11190:907] {
data = {
token = "IVZ2ciRkbVtDLUl3YmhwOTkyXzpRR1M3LUUsRiElfWF6T3I6dCxsRWg6di1XcyR6OTUzZHhVazdLTEJ7blU5O258d2xRTXg0VUxwQXBlNHRSOXd2VXZ1aG1RfFhQQjJsSkkoc2IuOTFyYkYodyhAe2RldXR1aDF3RClXWyhoMiU=";
};
meta = (
);
}
I believe the data is in JSON format. In that case, this should work.
NSError *error = nil;
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:urlData options:0 error:&error];
NSString *token = [[responseDict objectForKey:#"data"] objectForKey:#"token"];
I'd just do this:
NSData *responseData = [NSData dataWithContentsOfURL:yourURL];
NSString *token = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions error:NULL][#"data"][#"token"];
It will be nil if there's any error.
In your Case, meta is an Array and data is a Dictionary. If your Response is properly formatted in JSON then you can use the below sample code to get the TokenString and metaArray.
Sample Code :
NSData *data = [NSData dataWithContentsOfURL:yourURL];
NSError* error = nil;
NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSString *token = [[responseDict objectForKey:#"data"] objectForKey:#"token"];
NSArray *meta = [responseDict objectForKey:#"meta"];
NSLog(#"\ntoken :: %#\nmeta :: %#",token,meta);
PS : To know more about JSON response , take a look at this Answer.

Break String that came from Json

I have a String that I got from a webserver which came in json format, but the string is huge with everything in it. I tried using the NSDICTIONARY but to no success. I was wondering what would be the best approach to break this string and add to different strings and eventually put it all in a class of strings. Thanks for the help! Here is my code:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:[NSURL URLWithString:#"http://mym2webdesign.com/meiplay/paulsuckedabuffalo/artists.php"]];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; //Or async request
returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSError *error=nil;
NSLog(#"HHHHHHHHHHHHHH"); //use this to know how far Im getting
NSLog(returnString); // Look at the console and you can see what the restults are
/*NSDictionary *results = [returnString JSONValue];
NSString *ID = [results objectForKey:#"ID"]; // for example
NSLog(#"ID Number: %#", ID);*/
Here is some of the log i get:
[{"ID":"1","name":"kevin","bio":"kevins bio"},{"ID":"1","name":"kevin","age":"20"},{"ID":"2","name":"Cesar","bio":"Cesar bio"},{"ID":"2","name":"Cesar","age":"19"},{"ID":"3", "name":"Katherine", "bio":"Katherines bio"},{"ID":"3", "name":"Katherine", "age":"22"}]
You are doing it wrong. Its a NSArray of NSDictionaries. So first you need to assign it to NSArray and then loop over it to get each individual NSDictionary. See below.
NSArray *results = [returnString JSONValue];
for(NSDictionary *record in results)
{
NSLog(#"ID: %#", [record objectForKey:#"ID"]);
}
You'll probably be better off just using NSJSONSerialization if your app is targeted for at or over iOS 5.0:
NSArray *JSONArray = [NSJSONSerialization JSONObjectWithData:returnData options:0 error:&error];
You might need to experiment with using NSArray vs. NSDictionary, etc., but this should be an overall simpler solution.
Try this :
NSArray *results = [returnString JSONValue];
for (int i=0; i<[results count];i++) {
NSDictionary *DetailDictonary=[results objectAtIndex:i];
NSString *strid=[DetailDictonary objectForKey:#"ID"];
NSString *strName=[DetailDictonary objectForKey:#"name"];
NSString *strBio=[DetailDictonary objectForKey:#"bio"];
// Or You can set it in Your ClassFile
MyClass *classObj=[[MyClass alloc] init];
classObj.strid=[DetailDictonary objectForKey:#"ID"];
classObj.strName=[DetailDictonary objectForKey:#"name"];
classObj.strBio=[DetailDictonary objectForKey:#"bio"];
[YourMainArray addObject:classObj]; //set YourClass to Array
[classObj release];
}

How to output JSon data in Objective-C

I am currently working on an iPhone application that takes in data from the following source:
I am trying to figure out how to parse it into a human readable format in say a text field.
My code so far is:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *urlString = [NSString stringWithFormat:#"http://dev.threesixtyapp.com/api/events.php?action=available&id=1"];
NSURL *url =[NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"%#",json);
}
http://stig.github.com/json-framework/ - SBJson is a great framework for encoding/decoding JSON. I recommend you check it out...It will parse it for you into an NSDictionary, and you simply set the text of the textfield equal to the value in the NSDictionary that you want. It's pretty straightforward using this framework. Your Json should just be a string when you pass it to the SBJson functions btw
First of all you have to understand the data structure of your json.
You can use JSON Viewer to view the data structure of your json.
As I can see you are getting array of objects consisting of event_title, date_from and date_to.
NSError *error = nil;
NSArray *jsonArry = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"%#",jsonArry);
for (NSDictionary *dict in jsonArry) {
NSString * title = [dict objectForKey:#"event_title"];
NSString * dateTo = [dict objectForKey:#"date_to"];
NSString * dateFrom = [dict objectForKey:#"date_from"];
NSLog(#"title=%#,dateTo=%#,dateFrom=%#",title,dateTo,dateFrom);
}

unable to parse json response from google

I am trying to parse Json response from This URL. I have used SBJsonParser, MTJSON and another parser but i am getting NULL in all three case.
apiUrlStr = #"http://maps.google.com/maps?output=dragdir&saddr=Delhi&daddr=Mumbai+to:hyderabad";
NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSUTF8StringEncoding error:nil];
SBJsonParser *json = [[[SBJsonParser alloc] init] autorelease];
NSDictionary *dictionary = [json objectWithString:apiResponse];
NSLog(#"dictionary=%#", [json objectWithString:apiResponse]);
2011-12-09 16:59:01.226 MapWithRoutes[2523:207] dictionary=(null)
Plz suggest me something
Oke if checked the url you gave with JSONlint.com and the JSON is not valid. thus can not be parsed by any library.
If you used JSONkit you can supply a NSError object with the parse call to see what went wrong:
NSError *error = nil;
NSDictionary *dictionary = [apiResponse objectFromJSONStringWithParseOptions:JKParseOptionNone error:&error];
if (!dictionary) {
NSLog(#"Error: %#", error);
}

Wunderground API json lookup on iPhone

Never touched json before. I'm trying to access some variables within the Wunderground weather API for Melbourne. For example, let's say I want to access the "wind_dir":"East" variable. This is my code thus far:
NSString *urlString =
[NSString stringWithFormat:
#"http://api.wunderground.com/api/key/geolookup/conditions/forecast/q/-33.957550,151.230850.json"];
NSLog(#"URL = %#", urlString);
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSArray *weatherInfo = [parser objectWithString:json_string error:nil];
for (NSDictionary *weatherString in weatherInfo)
{
NSLog(#"some weather info = %#", [[[weatherString objectForKey:#"response"] objectForKey:#"current_observation"] objectForKey:#"wind_dir"]);
}
My code reaches the for loop and crashes with this error: -[NSCFString objectForKey:]: unrecognized selector sent to instance.
I'm not 100% sure what's causing the crash, and whether my path to the "wind_dir" variable is correct, though they could well be the same problem.
Thanks in advance for any help.
either the "response" property or the "current_observation" propery is string and not dictionary.
the error you are getting is that you are trying to call "objectForKey" on a string.
after looking at the result of the API, it seems that you are not getting an array.
You should do something like this:
NSDictionary *weatherInfo = [parser objectWithString:json_string error:nil];
NSLog(#"some weather info = %#", [[weatherInfo objectForKey:#"current_observation"] objectForKey:#"wind_dir"]);
instead of your for statement.