Decode JSON to NSArray or NSDictionary - objective-c

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.

Related

Am stuck in parsing Push Notifications

I want to fetch value of description from the below response. In body few more key-value pairs are there. I have tried, unfortunately am failing to crack. My code is in Objective C.
And My code for Parsing as below
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:notification.request.content.userInfo options:0 error:NULL];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"After Validation JSON VALUE IS : %#", jsonString);
NSData *BodyData = [NSJSONSerialization dataWithJSONObject:[[[notification.request.content.userInfo objectForKey:#"aps"] objectForKey:#"alert"] objectForKey:#"body"] options:0 error:NULL];
NSString *BodyString = [[NSString alloc] initWithData:BodyData encoding:NSUTF8StringEncoding];
NSLog(#"After Validation JSON VALUE IS : %#", BodyString);
Here is my complete response. I want to fetch all the values from body section.
{
"aps":{
"alert":{
"title":"Your bill is ready from shop My Store",
"body":"{\"shop_id\":\"16\",\"shop_name\":\"My Store\",\"description\":\"Thank you for Shopping\",\"notification_type\":\"bill\",\"shop_category\":\"entertainment\",\"bill_date\":\"2018-01-13\",\"bill_url\":\"dXBsb2FkLzRvcmVfMDExMzIwMTgtMTY0NjI5LnBkZg==\",\"approve\":1}"
},
"sound":"1"
},
"gcm.message_id":"0:1515842219916508%a1c76c71a1c76c71",
"gcm.notification.vibrate":"1"
}
convert your body string to json
NSString*bodyKeyValue = #"{\"shop_id\":\"16\",\"shop_name\":\"My Store\",\"description\":\"Thank you for Shopping\",\"notification_type\":\"bill\",\"shop_category\":\"entertainment\",\"bill_date\":\"2018-01-13\",\"bill_url\":\"dXBsb2FkLzRvcmVfMDExMzIwMTgtMTY0NjI5LnBkZg==\",\"approve\":1}"; //[[[notification.request.content.userInfo objectForKey:#"aps"] objectForKey:#"alert"] objectForKey:#"body"];
NSData *data = [bodyKeyValue dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* jsonOutput = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"%#",jsonOutput);
NSLog(#"approve Key value:%#",[jsonOutput objectForKey:#"approve"]);

How do I retrieve JSON data not on it's top level in Objective-C?

I have JSON data that looks as such:
{
"dataset": {
"id": ,
"dataset_code": "",
"database_code": "",
"name": "",
"description": "",
"refreshed_at": "",
}
}
When I go to NSLog the JSON data using the "dataset" identifier it prints fine. However I want to access the next level of JSON data which is what I'm looking to use. However, when I try to NSLog the next level I get an error in xcode. My code looks as such:
NSString *query = #"jsonwebsite.com";
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:query]];
_Array = [[NSMutableArray alloc] init];
_Array = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
So if I use this it's logs fine.
NSString *testString = [_Array valueForKey:#"dataset"];
NSLog(#"%#",testString);
But as mentioned, I'm looking for the next set of data and when I try this, it gives an error.
NSString *testString = [_Array valueForKey:#"name"];
NSLog(#"%#",testString);
It returns (null). How would I be able to access the name field in this JSON data?
There is a lot wrong with your code.
_Array = [[NSMutableArray alloc] init];
_Array = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
There is no point to creating an empty array in the first line, only to replace it with a different object in the second line.
Your data contains a dictionary of dictionaries, not an array. You should create a variable dictionary:
NSMutableDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
You should not use valueForKey to fetch values from your dictionary. That is a KVO method. Use objectForKey instead, or better yet, use modern dictionary syntax:
NSMutableDictionary *dataSet = dictionary[#"dataset"];
NSString *name = dataSet[#"name"];
if (name == nil) {
NSLog(#"name is nil");
}
else if (name.length == 0) {
NSLog(#"name is empty");
}
else {
NSLog(#"Name is %#", name);
}
your json is a NSDictionary not a NSMutableArray,you used a NSMutableArray to recieve a NSDictionary was wrong.
test this:
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
NSDictionary *subDict = dict[#"dataset"];
NSLog(#"%#", subDict);
NSLog(#"%#", subDict[#"name"]);
Change this code:
NSString *query = #"jsonwebsite.com";
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:query]];
_Array = [[NSMutableArray alloc] init];
_Array = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
NSString *testString = [_Array valueForKey:#"name"];
NSLog(#"%#",testString);
into this:
NSString *query = #"jsonwebsite.com";
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:query]];
_Array = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
NSDictionary *dataSet = [_Array objectForKey:#"dataset"];
NSString *testString = [dataSet objectForKey:#"name"];
NSLog(#"%#",testString);

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];

Using NSJSONSerialization for mac

I'm trying to user NSJSONSerialization in a mac app, but i can't get it working, I'm trying to get it to load UserTimeline, and just show the text of the last tweet, and thats it, but I can't seem to find the proper way to use it. the api i have tried to use :
http://api.twitter.com/1/statuses/user_timeline.json?screen_name=AlexTrott_
And
http://twitter.com/statuses/user_timeline/AlexTrott_.json
but neither of them i've had look, this is how i've been trying to use NSJSONSerialization :
NSString *tweets = [NSURL URLWithString:#"http://twitter.com/statuses/user_timeline/AlexTrott_.json"];
NSData *jsonData = [tweets dataUsingEncoding:NSUTF8StringEncoding];
NSError *e = nil;
NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&e];
NSLog(#"%#", json);
that is just what i've been using to see if it's loaded them, but it's been failing me.
I also tried was going to try this method http://www.raywenderlich.com/5492/working-with-json-in-ios-5 however thats solely for iOS and i don't know how i'd get it to work on Mac.
Any links on how to use NSJSONSerialization for mac would be brilliant, or any help with could would also be a major thanks. I tried getting help on the apple developer forums, but no luck there.
NSURL *tweets = [NSURL URLWithString:#"http://twitter.com/statuses/user_timeline/AlexTrott_.json"];
//NSData *jsonData = [tweets dataUsingEncoding:NSUTF8StringEncoding];
//NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&e];
NSData *jsonData=[NSData dataWithContentsOfURL:tweets];
NSError *e = nil;
id yourJsonData=[NSJSONSerialization JSONObjectWithData:jsonData options:
NSJSONReadingMutableContainers error:&error];
NSLog("%#",yourJsonData );//you must get a json object here
//let's assume you need to get the key kalled user_name from your JSON Response
NSDictionary *theJson=[yourJsonData objectForKey:#"user_name"];
for(NSMutableArray *usernames in theJson){
// do something with usernames from your object
}
My application also receives his last tweet. You should consider the limits to the server with these requests (350 per hour). If you exceed this limit, there is no nsarray in nsdata it is nsdictionary, which describes the error and the request, which will undoubtedly be taken into account. I did it this way:
NSError* error = nil;
id responseBody = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
if (error) {
[[NSAlert alertWithError:error] runModal];
}
if ([responseBody respondsToSelector:#selector(objectAtIndex:)]) {
else {
if ([responseBody count]) {
NSString* currentStatus = [[responseBody objectAtIndex:0] objectForKey:#"text"]; //now you can do smth with your status))
}
else {
NSLog(#"You have not tweetted yet!");
}
}
}
else if([responseBody respondsToSelector:#selector(objectForKey:)]) {
NSString* error = [responseBody objectForKey:#"error"];
NSLog(#"CURRENT STATUS ERROR => %#", error);
}