Reading JSON to NSString and getting a specific entry - objective-c

I have a problem with the SBJSON Parser. I'm trying to get some information from a website which gives back a json file. Then I parse that into a string and then into a dictionary (works fine). But when I want the last element (name) from that dict it just gives me an error. Here's my code:
SBJsonParser *parser = [[SBJsonParser alloc] init];
self.videoId = videoId;
// Grab the contents from the url and save it in a string
NSString *content = [NSString stringWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://gdata.youtube.com/feeds/api/videos/%#?alt=json",videoId]] encoding:NSUTF8StringEncoding error:nil];
// Save the information from the string in a dict
NSDictionary *dict = [parser objectWithString:content error:nil];
NSArray *string = [[dict objectForKey:#"entry"] objectForKey:#"author"];
NSLog(#"%#", string);
Here's the output:
2012-10-10 11:11:47.731 quoteGen[13862:c07] (
{
name = {
"$t" = CommanderKrieger;
};
uri = {
"$t" = "http://gdata.youtube.com/feeds/api/users/CommanderKrieger";
};
}
)
How do I get the name or uri?

NSString *name = [[[string objectAtIndex:0] objectForKey:#"name"] objectForKey:#"$t"];
NSString *urlString = [[[string objectAtIndex:0] objectForKey:#"uri"] objectForKey:#"$t"];
I think it will be helpful to you.

Related

reading JSON, null

Here's my JSON
{
"name": "abe",
}
and this is a part of my code
self.fileRoot = [[NSBundle bundleForClass:[self class]] pathForResource:#"name" ofType:#"json"];
self.jsonString = [NSString stringWithContentsOfFile:self.fileRoot encoding:NSUTF8StringEncoding error:nil];
self.jsonParser = [[SBJsonParser alloc] init];
self.dict = [self.jsonParser objectWithString:self.jsonString];
NSLog(#"\njsonString: %#\njsonParser: %#\ndict: %#\n", self.jsonString, self.jsonParser, self.dict);
the log is:
jsonString: {
"name": "abe",
}
jsonParser: <SBJsonParser: 0x8d6b7f0>
dict: (null)
I have the problem that's why dict said "(null)"
I'm pretty sure this code used to work when I tested it last time(about 3 months ago)
Any suggestion? Thank you in advance.
Remove the comma from the key value pair, since you just have a single name-value pair in json string
//convert string to NSData
NSString* str = #"{'name':'abe'}";
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
//create dictionary
NSError *error = nil;
NSDictionary *dict = [NSJSONSerialization
JSONObjectWithData: data
options:0
error:&error];
NSLog(#"Name: %#", dict[#"name"]);

Converting NSString to NSDictionary / JSON

I have the following data saved as an NSString :
{
Key = ID;
Value = {
Content = 268;
Type = Text;
};
},
{
Key = ContractTemplateId;
Value = {
Content = 65;
Type = Text;
};
},
I want to convert this data to an NSDictionary containing the key value pairs.
I am trying first to convert the NSString to a JSON objects as follows :
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
However when I try :
NSString * test = [json objectForKey:#"ID"];
NSLog(#"TEST IS %#", test);
I receive the value as NULL.
Can anyone suggest what is the problem ?
I believe you are misinterpreting the JSON format for key values. You should store your string as
NSString *jsonString = #"{\"ID\":{\"Content\":268,\"type\":\"text\"},\"ContractTemplateID\":{\"Content\":65,\"type\":\"text\"}}";
NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
Now if you do following NSLog statement
NSLog(#"%#",[json objectForKey:#"ID"]);
Result would be another NSDictionary.
{
Content = 268;
type = text;
}
I think you get the array from response so you have to assign response to array.
NSError *err = nil;
NSArray *array = [NSJSONSerialization JSONObjectWithData:[string dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&err];
NSDictionary *dictionary = [array objectAtIndex:0];NSString *test = [dictionary objectForKey:#"ID"];NSLog(#"Test is %#",test);
Use this code where str is your JSON string:
NSError *err = nil;
NSArray *arr =
[NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding]
options:NSJSONReadingMutableContainers
error:&err];
// access the dictionaries
NSMutableDictionary *dict = arr[0];
for (NSMutableDictionary *dictionary in arr) {
// do something using dictionary
}
Swift 3:
if let jsonString = styleDictionary as? String {
let objectData = jsonString.data(using: String.Encoding.utf8)
do {
let json = try JSONSerialization.jsonObject(with: objectData!, options: JSONSerialization.ReadingOptions.mutableContainers)
print(String(describing: json))
} catch {
// Handle error
print(error)
}
}
Use the following code to get the response object from the AFHTTPSessionManager failure block; then you can convert the generic type into the required data type:
id responseObject = [NSJSONSerialization JSONObjectWithData:(NSData *)error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] options:0 error:nil];

Decode JSON to NSArray or NSDictionary

I hope to decode the JSON data below:
{
"content":
[
{
"1":"a",
"2":"b",
"3":"c",
"4":"d",
"mark":"yes"
}
]
}
Not sure if put it in NSArray or NSDictionary
Welcome any comment
which iOS version are you using? in iOS 5 you have the NSJSONSerialization class to parse JSON data, if you need to target older iOSs or MAC OSX you should use third parties lib such as SBJSON. The string posted will be a NSDictionary with an array with one dictionary. The array will be accessible using the key #"content"
In code:
NSString * jsonString = #"blblblblblb";
NSStringEncoding encoding;
NSData * jsonData = [jsonString dataUsingEncoding:encoding];
NSError * error=nil;
NSDictionary * parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
In SWIFT 2.0:
let jsonString = "blblblblblb"
let encoding = NSUTF8StringEncoding
let jsonData = jsonString.dataUsingEncoding(encoding)
guard let jData = jsonData else {return}
do {
let parsedData = try NSJSONSerialization.JSONObjectWithData(jData, options: [])
} catch let error {
print("json error: \(error)")
}
[UPDATE]
The NSJSONSerialization class is also available for 10.7 my comment wasn't correct.
That particular string will decode into an NSDictionary because the outermost thing is a JSON object which maps onto a NSDictionary for every JSON implementation I have ever seen. If you want to process an arbitrary string, you'll need to test what you get back
NSError *jsonError;
id parsedThing = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
if (parsedThing == nil)
{
// error
}
else if ([parsedThing isKindOfClass: [NSArray class]])
{
// handle array, parsedThing can be cast as an NSArray safely
}
else
{
// handle dictionary, parsedThing can be cast as an NSDictionary
// NB only dictionaries and arrays allowed as long as NSJSONReadingAllowFragments
// not specified in the options
}
stringWithContentsOfFile:encoding: is deprecated in iOS<6
for iOS 6+
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"contents" ofType:#"json"];
NSError * error=nil;
NSString *jsonString = [NSString stringWithContentsOfFile:filePath encoding:nil error:&error];
NSData * jsonData = [jsonString dataUsingEncoding:nil];
NSArray * parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
contents.json file is in your bundle.
You can do the following:
NSData *data = ...; //JSON data
NSError *jsonError = nil;
[NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
You will get back an NSDictionary containing an NSArray containing a single NSDictionary containing five NSString objects.
I used google speech recognition API and I was getting a json response which was not directly parsable on iOS. Results samples were like :
First I tried saying Hello 1 2 3 which was recognised without issues. Json response was :
{"result":[]}
{"result":[{"alternative":[{"transcript":"hello 123","confidence":0.59780568},{"transcript":"hello 1 2 3"}],"final":true}],"result_index":0}
Or when talked for too long, I got a 404 HTML like below :
<html><title>Error 400 (Bad Request)!!1</title></html>
And when I spoke gibberish , I got :
{"result":[]}
So to parse all such response, I used the below code :
NSString *msg = #"Could not synthesize !";
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"responseString: %#",responseString);
if([responseString containsString:#"transcript"]&&responseString.length>25)
{
responseString = [responseString stringByReplacingOccurrencesOfString:#"{\"result\":[]}" withString:#""];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
if(dictionary!=nil)
if(dictionary.allValues.count>0)
{
NSArray *array =[dictionary valueForKeyPath:#"result.alternative.transcript"];
if(array)
{
NSArray *array2 = [array objectAtIndex:0];
if(array2)
{
NSLog(#"%#",[array2 objectAtIndex:0] );
msg = [array2 objectAtIndex:0];
};
}
}
}
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Google Response" message:msg delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
Hope this helps someone.

Want to split the JSON from the URL not the response

I want to split the json part from this URL in my iPhone application.
http://vkontakte.ru/login_success.html#session={"expire":"1272008089","mid":"100172","secret":"9c8d8f0305","sid":"1131703552161ae352a1256402e3140d7cbde41b1602a93d15472c82"}
I tried and and saved the JSON into a NSString but what i am getting is
http://vkontakte.ru/api/login_success.html?session=%7B%22mid%22:113158415,%22secret%22:%227ce58bfcd3%22,%22sid%22:%2203831b43c1bb992f9477efbfe96e83f6ecff1c1b661315ac0a20719cf57a44%22,%22expire%22:0%7D
This is not coming in JSOn Format. Below is my code
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *url = [request URL];
NSError* error;
NSLog (#"json path %#",url);
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSURLRequest *request1 = [NSURLRequest requestWithURL:url];
NSString *json_string = [url absoluteString];
NSArray *arr = [json_string componentsSeparatedByString:#"="];
json_string = [arr objectAtIndex:1];
// parse the JSON response into an object
// Here we're using NSArray since we're parsing an array of JSON status objects
NSArray *statuses = [json_string JSONValue];
NSLog(#"%#",error);
// Each element in statuses is a single status
// represented as a NSDictionary
for (NSDictionary *status in statuses)
{
// You can retrieve individual values using objectForKey on the status NSDictionary
// This will print the tweet and username to the console
NSLog(#"%# - %#", [status objectForKey:#"secret "], [[status objectForKey:#"mid"] objectForKey:#"sid"]);
}
return YES;
}
How can move further?
Try replacing:
NSString *json_string = [url absoluteString];
with
NSString *json_string = [[url absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];.
That's a really strange thing you're doing, though. Why does the URL have JSON in it?

Parsing nested JSON objects with JSON Framework for Objective-C

I have the following JSON object:
{
"response": {
"status": 200
},
"messages": [
{
"message": {
"user": "value"
"pass": "value",
"url": "value"
}
]
}
}
I am using JSON-Framework (also tried JSON Touch) to parse through this and create a dictionary. I want to access the "message" block and pull out the "user", "pass" and "url" values.
In Obj-C I have the following code:
// Create new SBJSON parser object
SBJSON *parser = [[SBJSON alloc] init];
// Prepare URL request to download statuses from Twitter
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:myURL]];
// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// Get JSON as a NSString from NSData response
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
//Print contents of json-string
NSArray *statuses = [parser objectWithString:json_string error:nil];
NSLog(#"Array Contents: %#", [statuses valueForKey:#"messages"]);
NSLog(#"Array Count: %d", [statuses count]);
NSDictionary *results = [json_string JSONValue];
NSArray *tweets = [[results objectForKey:#"messages"] objectForKey:#"message"];
for (NSDictionary *tweet in tweets)
{
NSString *url = [tweet objectForKey:#"url"];
NSLog(#"url is: %#",url);
}
I can pull out "messages" and see all of the "message" blocks, but I am unable to parse deeper and pull out the "user", "pass", and "url".
Solved:
NSArray *tweets = [[results objectForKey:#"messages"] valueForKey:#"message"];
Array({
0=>Dictionary({
response = Array({
0=>Dictionary(Status = 200)
})
}),
1=>Dictionary({
messages = Array({
0=> Dictionary({
message = Array({
0=>Dictionary({
user = value,
pass=value,
url=value
})
})
})
})
})
})
So, to access dictionary for user, pass, url,
nsarray *arr = jsonmainarray;
arr = [[[jsonmainarray objectAtIndex: 1] objectforkey:#"messages"] objectatindex: 0];
nsdictionary *dict = [arr objectatindex: 0];
arr = [dict objectforkey:#"message"];
dict = [arr objectatindex: 0]; // Dictionary with user, pass, url
there is an easier way (in my opinion) to do JSON parsing :)
- (void)loadJSONData:(NSString *)u{
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://expandurl.appspot.com/expand?url=%#", u]];
NSData *rawJsonData = [NSData dataWithContentsOfURL:url];
CJSONDeserializer *parser = [CJSONDeserializer new];
NSError *error;
NSDictionary *jsonDictionary = [parser deserializeAsDictionary:rawJsonData error:&error];
[parser release];
NSArray *array = [jsonDictionary objectForKey:#"urls"];
}
All you have to do is to use JSON touch... like Sheehan Alam mention.
Say that you got this line of JSON data:
{
"end_url" = "http://www.youtube.com";
redirects = 0;
"start_url" = "http://www.youtube.com";
status = OK;
urls = (
"http://www.youtube.com"
);
}
then in your JSONDictonary the data can be accessed by doing:
[jsonDictionary objectForKey:#"urls"]; //This will return an Array since URLS is a array
[jsondictionary objectForKey:#"en_url"]; //this will return an NSString since end_url is a string
Hope this help people as much as it helped me =)
sincerely yours
Kristian