Am stuck in parsing Push Notifications - objective-c

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

Related

issue with '/' while passing parameter to API

I have the following code:-
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
NSData *data = [surveyAnswerForCurrentSurvey dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *answerJson = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSMutableDictionary *answer = [answerJson mutableCopy];
if([answer valueForKey:question.name] != nil){
[answer setObject:textField.text forKey:question.name];
}
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[answer copy] options:0 error:nil];
NSLog(#"ns data is %#",jsonData);
NSString *json = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"json string:%#", json);
NSDictionary *answersDict = #{#"answers_json":json};
NSData *answersAsData = [NSJSONSerialization dataWithJSONObject: answersDict options:0 error:nil];
NSString *answersJSONStringify = [[NSString alloc] initWithData: answersAsData encoding:NSUTF8StringEncoding];
parameters = #{#"survey_answer":answersJSONStringify};
[self submitSurveyAnswer];
the result is having three '/' which is making the parameter to be passed in API in improper format.
parameter:-
{ "survey_answer" = "{\"answers_json\":\"{\\\"7d2c591c-9056-405c-9509-03266842b7‌​e5\\\":[\\\"1\\\"],\‌​\\"4090442c-90ce-42c‌​2-aae8-7c812b7c0f04\‌​\\":\\\"test from postman\\\",\\\"54bdcf13-e500-418a-8bab-d0639e7e1e28\\\":\\\‌​"2\\\",\\\"63bb0722-‌​7099-4820-a400-36b89‌​38c6ae8\\\":\\\"hell‌​o\\\",\\\"f884a7d1-f‌​9d9-4563-bb6e-945386‌​64f3bd\\\":\\\"test from cms and iphone\\\",\\\"ed3acc20-4ae4-493e-ac55-4d2d0f282886\\\":\\\"‌​1\\\"}\"}"; }
This line
NSDictionary *answersDict = #{#"answers_json":json};
Creates a JSON object with one key whose value is the string result of serialising your original JSON object. All of the " in the string need to be escaped with \ so this is what it does, i.e.
{ "answer" : "{ "foo" : "bar" }" }
Is not legal because of the embedded quotes in the string. So it does this:
{ "answer" : "{ \"foo\" : \"bar\" }" }
Then you get multiplication of backslashes when you print the resulting string because the backslashes need to be escaped.
To fix the problem, use the JSON object, not its serialisation. the line above becomes:
NSDictionary *answersDict = #{#"answers_json": [answer copy]};

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

iOS to parse JSON?

I am getting the following response from server
[{"id":"16","name":"Bob","age":"37"},{"id":"17","name":"rob","age":"28"}];
I am using AFNetworking framework for it,
I am getting the above response in NSData and then using the the below code, I am able to collect the data in NSDictionary
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingAllowFragments error:&error];
But how to parse the "name" and "age" value from that NSDictionary?
You expected NSDictionary but your response gives you array of dictionaries, try this:
NSArray *array = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingAllowFragments error:&error];
for (NSDictionary *dict in array)
{
NSLog(#"Name: %#, age: %#", dict[#"name"], dict[#"age"]);
}
//Extended
From the comment below it looks like you have a string from the response, not NSArray as you show in the code above.
You can parse string to get the data you want or you can convert it back to the json and NSArray:
NSString * jsonString = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingAllowFragments error:&error];
NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
//As I post above
Now you should have an NSArray and my code should do the job.

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.