Unable to create keys into NSDictionary after parsing JSON - ios

I have seen similar topics to this but none that seem to address my issue. I am receiving this JSON:
("taskname: 1738 Main St., taskdescription: install flooring, worker: Jim Davis, approver: John Jones",
"taskname: 300 Market St., taskdescription: paint ceiling, worker: John Smith, approver: Bob Johnson"
)
This is the code that I am using to ultimately create a NSDictionary:
NSURL *url = [NSURL URLWithString:MY_JSON_URL];
NSData *data = [NSData dataWithContentsOfURL:url];
NSDictionary *JSONDictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:NULL];
NSArray *JSONarray = [JSONDictionary valueForKeyPath:#"feed.entry.content.$t"];
NSDictionary *taskDictionary = JSONarray[0];
NSLog(#"array content = %#",JSONarray)
The array values are correct but when I try to key into the dictionary, the key does not exist
NSLog(#"dictionary contents = %#", taskDictionary[#"taskname"]);
I am new to JSON so any help is much appreciated!

The JSON you are receiving is not valid, hence the key 'taskname' doesn't exist.
It should be in the following format:
[{"taskname": "1738 Main St.", "taskdescription": "install flooring", "worker": "Jim Davis", "approver": "John Jones"},
{"taskname": "300 Market St.", "taskdescription": "paint ceiling", "worker": "John Smith", "approver": "Bob Johnson"}]

Related

How to parse Dynamic changes in json value. Dictionary with 2 nested dic & then array and then dic again

Dictionary with two nested dictionary and then array and then dictionary again how can i write code generally for objective c ,iOS 8;
{
"brands": {
"Clinique": {
"Foundation": {
"Even Better Makeup SPF 15": {
"productName": "Even Better Makeup SPF 15",
"colors": [
{
"id": "30816",
"client_id": "1422956000sjdaC",
"product_id": "190",
"shade_name": "Alabaster",
"shade_code": "#F0C9AE",
"color_id": null,
"image_url": "",
"price": "",
"offer": "",
"created_by": "1422956000sjdaC",
"created_date": "2015-03-06",
"sku_id": "",
"product_web_url": "",
"brand_id": "Clinique",
"product_name": "Even Better Makeup SPF 15",
"makeup_type": "Foundation",
"color_family": "cool"
},
As I can see, your JSON response is sending Product details, so the
"brands": {
"Clinique": {
"Foundation": {
will remain same always, and the response below it will change according to products.
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSDictionary *productsDict = [[jsonDictionary objectForKey:#"brands"] objectForKey:#"Clinique"] objectForKey:#"Foundation"];
NSArray *keys=[productsDict allKeys];
for (int i = 0; i < keys.count; i++) {
NSDictionary *prodSingle = [productsDict objectForKey:[NSString StringWithFormat:#"%#",keys[i]]];
}
Now you have prodSingle, use this to get data of each product.
Note: Untested, I'll provide a tested version if this doesn't work.
EDIT:
As you said only brands key will remain constant and other will change dynamically,
you should do this :
So what you can do is create a NSDictionary with jsonData(response data) like this:
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
create a dictionary of brands
NSDictionary *brandsDict = [jsonDictionary objectForKey:#"brands"];
Now get all the keys:
NSArray *keys= [brandsDict allKeys];
Now use each key you got in Array to fetch data accordingly.

Multi level JSON reading and writing IOS8

So the last two days I have been struggling to get data from and to a JSON file, this is because it has multiple levels and the same names. I did not set up this file and can't change the structure so I have to get it working in the way it is. To Pharse JSON form a single level is no problem and it works fine, what I need is to get separate data block from "GOV" and "PRIV" then I need a data block "GENERAL" and "LOCAL" and within those I need to be able to get the "Hospital information as a block but also the separate values. Now I have been trying to get this done for two days and I know im doing something wrong but cant figure it out. I do get data back for example the "GOV" block but then in the output window it is showing a array with access data (<__NSCFArray 0x7fe711f58800>) and the output... I cant break up this output and that is what I need because every value needs to be in a text file in a tableview cell. I know { } denotes NSDictionary [ ] denotes NSArray and I have been reading a lot about JSON and I get the concept but There is little to non for me understandable info when it comes to multi level JSON and equal names (hospital) in this case. I have tried all the available option I could find here on StackOverflow but no succes. So if somebody can push me in the right way I will be gratefull.. part of the code:
NSURL *url = [NSURL URLWithString:getDataURL];
NSData * data = [NSData dataWithContentsOfURL:url];
_jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
_AppListArray = [[NSMutableArray alloc] init];
NSArray *wrapper= [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSDictionary *avatars = [wrapper objectAtIndex:0];
for(NSDictionary *apps in _jsonArray) {
if([[apps objectForKey:#"title"] isEqualToString:#"GOV"]){
NSDictionary*tmp = [apps objectForKey:#"hospital"];
_AppListArray = [tmp objectForKey:#"area"];
}
}
//returns error because _ApplistArray is an array and it can't read the data from the objectkey
for (int i = 0; i < _jsonArray.count; i++)
{
NSString *appName = [[_AppListArray objectAtIndex:i] objectForKey:#"hospitalname"];
NSString *appCondition = [[_AppListArray objectAtIndex:i] objectForKey:#"condition"];
NSString *app avgrating = [[_AppListArray objectAtIndex:i] objectForKey:#"avgrating"];
[_AppListArray addObject:[[Applist alloc]initWithAppName:appName andAppCondition:appCondition andAppURL:appURL]];
}
The _ApplistArray does return the 1ste Hospital data block but as an array and this is were I get stuck.. I need to get another level deeper.....Again the solution probably is easy but JSON is something I never worked with this is my first go. The JSON where I need to get the data from:
[
-{
-hospital: {
-area: [
-{
-hospital: [
-{
hospitalname: "ABC",
avgrating: "2,6",
condition: "UPDATE NEEDED",
},
-{
hospitalname: "DEF",
avgrating: "4,2",
condition: "FINE",
},
],
name: "GENERAL"
}
]
},
title: "GOV"
},
-{
-hospital: {
-area: [
-{
-hospital: [
-{
hospitalname: "GHI",
avgrating: "3",
condition: "INSTALL NEW",
},
-{
hospitalname: "JKL",
avgrating: "0",
condition: "NEW",
},
],
name: "LOCAL"
}
]
},
title: "PRIV"
}
]
Here you go.
NSArray *hospitals = [jsonArray objectForKey:#"mainKey"];// I assumed you getting with some key but change based on your requirement
for (NSDictionary *mainData in hospitals){ // Start of Main Hospital
NSDictionary *hospital = [mainData objectForKey:#"hospital"];
NSArray *areas = [hospital objectForKey:#"area"];
for(NSDictionary *area in areas){// Start of Area
NSArray *innerHospitals = [area objectForKey:#"hospital"];
for(NSDictionary *innerHospital in innerHospitals){
NSString *hospitalName = [innerHospital objectForKey:#"hospitalname"];
NSString *avgrating =[innerHospital objectForKey:#"avgrating"];
NSString *condition =[innerHospital objectForKey:#"condition"];
// Do What Ever you want here
}
NSString *name =[area objectForKey:#"name"];
}// End Of Area
NSString *title =[mainData objectForKey:#"title"];
} // End of Main Hospital
I haven't tested it. But i assume this will work. Have a try and let me know what happens.
The problem is that you need 2 for loops for each "Area".
Area is an Array (1st loop) and each hospital is another Array (2nd loop).
And inside each hospital element is the dictionary with the values you need.
ignoring loops this is how you get the first hospitalname(ABC) assuming _AppListArray has the contents of Area
NSString *appName = _AppListArray[0][#"hospital"][0][#"hospitalname"];
For each 0 you will replace it with the counters for the for loops.

Objective C parse JSON

I Have this result JSON below that i get from my wcf service which i want to iterate through in my ipad app.I use the code below to parse the result json but the app gives error. How can iterate through this dictionary and get the items.
IOS Code:
myArray = [NSMutableArray array];
// Do any additional setup after loading the view.
NSString* URL = #"http://www.unluapps.com/Service1.svc/ListTopReports";
NSDictionary *dictionary = [JSONHelper loadJSONDataFromURL:URL ];
NSString *result=[dictionary valueForKey:#"ListTopReportsResult"];
NSLog(#"%#",result);
/* for (NSString* key in result ) {
id value=[result objectForKey:key];
NSLog(#"%# -+",value);
}
*/
JSON:
{
ListTopReportsResult: [
{
AppUserID: null,
Author: "Joe Matthew",
Company: "Coca-Cola",
Country: "Poland",
CreationDate: "8/20/2014 4:32:00 AM",
EndDate: null,
ResearchReportID: "2",
Sector: "Soft Drinks",
Summary: "da ascon casmld lmasdlasd",
Title: "Can Coca-cola beat the market?",
URL: "2123123.pdf"
},
{
AppUserID: null,
Author: "martina pawlik",
Company: "Cimsa",
Country: "Poland",
CreationDate: "8/20/2014 4:31:00 AM",
EndDate: null,
ResearchReportID: "1",
Sector: "Cement",
Summary: "asd adas asd asdasd asdasdasd",
Title: "Poland's cement sector is on the rise",
URL: "1123123.pdf"
}
]
}
Try this:
NSArray *result=[dictionary valueForKey:#"ListTopReportsResult"];
Because in your JSON, there is an array for key ListTopReportsResult.
Hope this helps. :)
Try doing something like this. This is not the exact solution and you'll have to work around your way.
NSString *link = [NSString stringWithFormat:#"yourServiceURL"];
NSString *encdLink = [link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:encdLink];
NSData *response = [NSData dataWithContentsOfURL:url];
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:response options: NSJSONReadingMutableContainers error: &error];
Now you have your data in the array and extract it out using objectForKey or valueForKey.You can use NSDictionary or NSArray as per your requirement.
Firstly get the array from the above code. Then extract out the image content like this :
_demoArray = [json valueForKey:#"yourKeyField"];
Now you have the values in your demoArray.
Hope this helps.

Parse JSON in Objective-C

I am new to Objective-C, and JSON so I am confused on how to do this. I have looked up tutorials, and made sure my JSON is valid.
I have a SQL server database that I am trying to access by parsing JSON. I have checked to make sure my JSON is valid. Whenever I attempt to parse the JSON is Objective-C, however, it always returns null.
Here is my JSON:
[
{
"ID": 1,
"Username": "Cray",
"Password": "fake",
"Active": 0,
"LastLogin": null
}
]
Here is my Objective-C code:
NSString *urlString = [NSString stringWithFormat:#"http://quacknasty.com/service.php"];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"test%#", json);
json always returns null when I do the NSLog
Easy one: Open the URL in a browser. You will see that you don't have valid JSON:
Conneection established.
[{"ID":1,"Username":"Cray","Password":"fake","Active":0,"LastLogin":null}]
You have to remove the echo of Connection established.\n
EDIT I: You have to use NSArray as root object, because the JSON string starts with []
EDIT II: Additionally you should set the correct HTTP Header fields as follows:
header('Content-Type: application/json; charset=utf-8');
Request to thi URL. Response is :
Conneection established.
<br />[{"ID":1,"Username":"Cray","Password":"fake","Active":0,"LastLogin":null}]
It's not json format

JSON Parsing Returns Null For Large Values Only

I'll keep this brief. I'm using this code to parse JSON from a local file into an array of objects:
-(void)populateData
{
NSString* sourcePath = [[NSBundle mainBundle]pathForResource:#"ships" ofType:#"json"];
//get json string
NSString* JSONData = [[NSString alloc] initWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil];
NSData* data = [JSONData dataUsingEncoding:NSUTF8StringEncoding];
//put json in array
ships = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(#"%#", ships);
}
(Note: only showed one for the sake of brevity, there's ~20 entries in each one)
This method works for JSON formatted like this:
[
{
"name": "Santa Maria",
"operator": "Kingdom of Spain",
"flag": "flag_spain"
}
]
It returns null for JSON formatted like this:
[
{
"name": "Santa Maria",
"operator": "Kingdom of Spain",
"flag": "flag_spain",
"launched": "November 19, 1890",
"fate": "Destroyed in Havana, Cuba in Feburary 1898."
"cost":"$4,677,788.75",
"image": "maine_img",
"image_attribution": "Image is in the public domain."
}]
I haven't the faintest idea of why the smaller one works while the larger one doesn't. Any help would be appreciated.
There is a comma missing after:
"fate": "Destroyed in Havana, Cuba in Feburary 1898."
It's due to a syntax error on this line:
"fate": "Destroyed in Havana, Cuba in Feburary 1898."
(missing comma at the end)
There are tools to spot this kind of errors. For instance, http://jsonlint.com. This one seems to have better error messages http://jsonformatter.curiousconcept.com/.
And excuse me, but converting from NSData to NSString and then back to NSData is just pointless. Just call dataWithContensOfFile: and be done with it.

Resources