Trouble reading JSON object using Obj-C - iphone

I am trying to read the following json object using the json-framework and obj-C
{
Sections = {
Now = "Wednesday 9 February 2011 02:40";
Section = (
{
Article = (
{
Exceprt = "text here";
ID = 49011;
Title = "text here";
Type = Politics;
audioCounter = 0;
commentsCounter = 0;
hasMore = false;
important = False;
likesCounter = 0;
photoCounter = 0;
time = "21:12";
timeStamp = "2/8/2011 9:14:16 PM";
timeStatus = True;
videoCounter = 0;
viewsCounter = 0;
},
{
Exceprt = "text here";
ID = 49010;
Title = "text here";
Type = Politics;
audioCounter = 0;
commentsCounter = 0;
hasMore = false;
important = True;
likesCounter = 0;
photoCounter = 0;
time = "20:45";
timeStamp = "2/8/2011 9:10:59 PM";
timeStatus = True;
videoCounter = 0;
viewsCounter = 0;
},
{
Exceprt = "text here";
ID = 49008;
Title = "text here";
Type = Politics;
audioCounter = 0;
commentsCounter = 0;
hasMore = false;
important = False;
likesCounter = 0;
photoCounter = 0;
time = "20:28";
timeStamp = "2/8/2011 9:09:44 PM";
timeStatus = True;
videoCounter = 0;
viewsCounter = 0;
}
);
ID = 22;
Name = "EN Live";
totalNews = 3416;
}
);
};
}
My intent is to have a list of the articles (list of dictionaries) so that I can later access them easily. I have been stuck a while on this and my code is giving me an error about calling a non existent method for NSArray which has led me to suspect that I am misunderstanding the json object. I am totally new to this and any help is greatly appreciated.
Here's my code:
NSDictionary *results = [jsonString JSONValue];
NSDictionary *Articles = [[results objectForKey:#"Sections"] objectForKey:#"Section"];
NSArray *ListOfArticles = [Articles objectForKey:#"Article"];
for (NSDictionary *article in ListOfArticles)
{
NSString *title = [article objectForKey:#"Title"];
NSLog(title);
}
Thanks !

First of all, those aren’t valid JSON data. Names (in name/value pairs) are strings and must be quoted. String values must always be quoted. Boolean values must be either true or false (lowercase). Check http://json.org/ and http://www.ietf.org/rfc/rfc4627.txt?number=4627 and http://jsonlint.com
Here’s the structure of your data:
The top level value is an object (dictionary)
This object has a name (key) called Sections whose value is itself another object (dictionary)
Sections has a name (key) called Section whose value is an array
Each element in the Section array is an object (dictionary)
Each element in the Section array has a name (key) called Article whose value is an array, as well as other names (keys): ID, title, totalNews
Each element in the Article array is an object
If your JSON data were valid, you could parse them as follows:
// 1.
NSDictionary *results = [jsonString JSONValue];
// 2.
NSDictionary *sections = [results objectForKey:#"Sections"];
// 3.
NSArray *sectionsArray = [sections objectForKey:#"Section"];
// 4.
for (NSDictionary *section in sectionsArray) {
// 5.
NSLog(#"Section ID = %#", [section objectForKey:#"ID"];
NSLog(#"Section Title = %#", [section objectForKey:#"Title"];
NSArray *articles = [section objectForKey:#"Article"];
// 6.
for (NSDictionary *article in articles) {
NSLog(#"Article ID = %#", [article objectForKey:#"ID"];
NSLog(#"Article Title = %#", [article objectForKey:#"Title"];
// …
}
}

Your JSON framework is probably parsing out an NSDictionary where you're expecting an NSArray. It'll let you assign an NSDictionary to an NSArray, but then you'll get a runtime exception when you attempt to call a method on your "array". Judging by the JSON you posted (which isn't correct JSON), this is what I would have my parsing code look like. The names of the NSDictionaries and NSArrays are simply named after the JSON attributes they represent.
NSDictionary* results = [jsonString JSONValue];
NSDictionary* sections = [results valueForKey:#"Sections"];
NSArray* section = [sections valueForKey:#"Section"];
NSArray article = [[section objectAtIndex:0] valueForKey:#"Article"];
for (NSDictionary* anArticle in article) {
NSLog(#"%#", [anArticle valueForKey:#"Title"]);
}

Related

Dictionary Value retrieve

In my application ,the dictionary value contains following content.How to retrieve the each and store it new array
contryArray(
{
checka0 = Thailand;
checka1 = Brazil;
checka10 = Marocco;
checka11 = Thailand;
checka12 = Jordan;
checka13 = Colombia;
checka14 = Kuwait;
checka3 = Mexico;
checka4 = "Saoudi Arabia";
checka5 = Chili;
checka7 = Australia;
checka8 = Malta;
checka9 = "South Africa";
checkb0 = havana;
checkb1 = Santos;
checkb10 = Casablanca;
checkb11 = Bangkok;
checkb12 = Aqaba;
checkb13 = Havana;
checkb14 = Shuwaikh;
checkb3 = Veracruz;
checkb4 = Jeddah;
checkb5 = "San Antonio";
checkb7 = Maersk;
checkb8 = Maraxklokk;
checkb9 = Durban;
checkc0 = 1;
checkc1 = "0.7";
checkc10 = 1;
checkc11 = "1.2";
checkc12 = 1;
checkc13 = "1.4";
checkc14 = 1;
checkc3 = "0.9";
checkc4 = "0.8";
checkc5 = "0.9";
checkc7 = "2.7";
checkc8 = "0.8";
checkc9 = "0.9";
}
For ex: checka0-checka14 in one array, Here the problem is checka2 and checka6 is not available, Im new bee in xcode,Please help me to retrieve
Your question is not clear. Possibly you need to get all keys in your dictionary and separating each item with specific word in it(checka/checkb/checkc).
If that is the case then,
You will get all the keys using:
NSArray *dictKeys = [yourDictionary allKeys];
You can implement this in multiple ways, one of them:
For storing it in same array:
for (NSString *key in [yourDictionary allKeys])
{
[yourArray addObject:[yourDictionary objectForKey:key]];
}
For storing it in seperate arrays:
for (NSString *key in [yourDictionary allKeys])
{
if([key rangeOfString:#"checka"].location != NSNotFound)
{
//add checka to first array
[yourFirstArray addObject:[yourDictionary objectForKey:key]];
}
else if([key rangeOfString:#"checkb"].location != NSNotFound)
{
//add checkb to second array
[yourSecondArray addObject:[yourDictionary objectForKey:key]];
}
...
}
if contryArray is your dictionary then access it as follow
[contryArray valueForKey:#"checka0"];
and go on adding this values to another array
You can use the following code:
- (void)filterDictionary:(NSDictionary *)dict
{
NSArray *allKeys = [dict allKeys];
NSMutableArray *allValues = [[NSMutableArray alloc]init];
for(id key in allKeys)
{
id value = [dict valueForKey:key];
[allValues addObject:[value stringValue]];
}
}

Merge two NSDIctionay in one NSDictonary

I want to merge two NSDictionary in one NSDictionary.
my first DIctionary
BreakFast Dates Dic {
"2012-07-24" = "27";
"2012-08-03" = "98";
"2012-08-06" = "4203";
"2012-08-23" = "0";
"2012-08-24" = "0";
"2012-09-11" = "36";
"2012-09-19" = "450";
"2012-09-24" = "36";
Goals = 3;
}
my second Dictonary
Dinner Dates Dic {
"2012-08-03" = "100";
"2012-08-27" = "0";
"2012-09-19" = "270";
Goals = 4;
}
i want to merge both dictionary into one. like if in breakfast i have "2012-09-19" and same date i have in dinner. i want to separate both values by comma (,) .
my resultant dictionary should be like this.
combine {
"2012-07-24" = "27,0";
"2012-08-03" = "98,100";
"2012-08-06" = "4203,0";
"2012-08-23" = "0,0";
"2012-08-24" = "0,0";
"2012-09-11" = "36,0";
"2012-09-19" = "450,270";
"2012-09-24" = "36,0";
Goals = 3,4;
}
NSMutableDictionary *combined = [objectDelegate.dataBreakFastSummary mutableCopy];
for(NSString *key in [combined allKeys])
{
NSString *breakfastDate = [objectDelegate.dataBreakFastSummary valueForKey:key];
NSString *dinnerDate = [objectDelegate.dataDinnerSummary objectForKey:key];
if(dinnerDate){
[combined setObject:[NSString stringWithFormat:#"%#,%#",breakfastDate, dinnerDate] forKey:key];
} else {
[combined setObject:[NSString stringWithFormat:#"%#,0",breakfastDate] forKey:key];
}
}
NSLog(#"Combine %#",combined);

sorting array of nested NSDictionary containing an array

Im quite new to iOS and objective.. heres my question..
if my array looks like this:
myArray = {
parentdict = {
childdict = {
aname = "Aname";
bname - "Bname";
cname = "Cname";
};
childarray = {
{
counter = "1";
close = "25236";
},
{
counter = "2";
close = "12458";
};
};
};
},
{
parentdict = {
childdict = {
aname = "Aname";
bname - "Bname";
cname = "Cname";
};
childarray = {
{
counter = "1";
close = "28556";
},
{
counter = "2";
close = "12118";
};
};
};
},
{
parentdict = {
childdict = {
aname = "Aname";
bname - "Bname";
cname = "Cname";
};
childarray = {
{
counter = "1";
close = "24356";
},
{
counter = "2";
close = "155628";
};
};
};
};
basically its an array of nested dictionary and inside one of the dictionary contains an array of dictionary (childarray) if i want to sort myArray by #"close" of array index 1, which is the one next to counter 2, exactly how should i do this?..(perhaps i should use NSSortDescriptor?)
thanks for the reply
You have presented your structure in the JSON format. I assume it is for sake of presenting it to the audience here. If you are actually starting with JSON string, you will have to convert it to nested NSArrayies and NSDictionaryies using some third-party libs or iOS 5 built-in classes..
Assuming you already have your top level NSArray* myArray, give it a try to the following code:
NSArray* myArray = // ... this is your array
NSArray* sorted_array = [myArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDictionary* left = obj1;
NSDictionary* right = obj2;
NSDictionary* left_parent_dict = [left objectForKey: #"parentdict"];
NSDictionary* right_parent_dict = [right objectForKey: #"parentdict"];
NSArray* left_child_array = [left_parent_dict objectForKey: #"childarray"];
NSArray* right_child_array = [right_parent_dict objectForKey: #"childarray"];
NSDictionary* left_child_first = [left_child_array objectAtIndex: 1];
NSDictionary* right_child_first = [right_child_array objectAtIndex: 1];
NSString* left_close = [left_child_first objectForKey: #"close"];
NSString* right_close = [right_child_first objectForKey: #"close"];
NSNumber* left_val = [NSNumber numberWithInt: [left_close intValue]];
NSNumber* right_val = [NSNumber numberWithInt: [right_close intValue]];
return [left_val compare: right_val];
} ];
You will need, of course, to add some checks which I omitted for simplicity.
If you want to get descending order modify the last statement to:
return [right_val compare: left_val];
I would also suggest you considering SQL database for complex data structures as pointed out by Niko.
Sorting an array can be quite complex, especially when the array contains nested objects. May be you should create an SQLite database
You should use iOS 5.0's built in JSON API. [Here's a link to a great tutorial.] (http://www.raywenderlich.com/5492/working-with-json-in-ios-5). JSON is really easy to work with. And that site also has great tutorials on Core Data (iOS's SQLite API) here. There are two more parts to that tutorial as well.
Try this
[array sortUsingComparator:(NSComparator)^(id obj1, id obj2){
int firstValue = [[obj1 objectForKey:#"someKey"] intValue];
int secondValue = [[obj2 objectForKey:#"someKey"] intValue];
int valueDiff = firstValue - secondValue;
return (valueDiff == 0) ? NSOrderedSame : (valueDiff < 0) ? NSOrderedAscending : NSOrderedDescending;
}];

How to store values of JSON in ARRAY/ String

I have the following JSON value:
-(
{ Key = IsEmail;
Value = 1; },
{ Key = TrackingInterval;
Value = 20; },
{ Key = IsBackup;
Value = 1; },
{ Key = WipeOnRestore;
Value = 1; }
)
How might I go about parsing this object into an array or string? - i.e. eack key values to be stored in an array and each Value to be stored in another array.
Please help me out with this.
Thanks :)
This approach uses the json-framework.
I've shortened your example:
NSString *jsonString = #"[{\"Key\":\"IsEmail\",\"Value\":\"1\"},{\"Key\":\"TrackingInterval\",\"Value\":\"20\"},{\"Key\":\"IsBackup\",\"Value\":\"1\"}]";
NSMutableArray *keys = [NSMutableArray array];
NSMutableArray *values = [NSMutableArray array];
NSArray *json = [jsonString JSONValue];
for (NSDictionary *pair in json) {
[keys addObject:[pair objectForKey:#"Key"]];
[values addObject:[pair objectForKey:#"Value"]];
}
NSLog(#"%#", keys);
NSLog(#"%#", values);
Output:
2011-05-18 14:23:55.698 [36736:207] (
IsEmail,
TrackingInterval,
IsBackup
)
2011-05-18 14:23:55.700 [36736:207] (
1,
20,
1
)
Refere
http://www.xprogress.com/post-44-how-to-parse-json-files-on-iphone-in-objective-c-into-nsarray-and-nsdictionary/
http://mobileorchard.com/tutorial-json-over-http-on-the-iphone/
http://mobile.tutsplus.com/tutorials/iphone/iphone-json-twitter-api/
http://blog.zachwaugh.com/post/309924609/how-to-use-json-in-cocoaobjective-c
Your data is not vald json, You may want to structure it more like this:
var theObj = { IsEmail: 1, TrackingInterval: 20, IsBackup: 1, WipeOnRestore: 1 };
Then you could populate your key and value arrays something like this:
var keys = new Array();
var values = new Array();
for (prop in theObj) {
keys.push(prop);
values.push(theObj[prop]);
}
if the JSON is in below format,
responseString=[ {
Key = IsEmail;
Value = 1;
},
{
Key = TrackingInterval;
Value = 20;
},
{
Key = IsBackup;
Value = 1;
},
{
Key = WipeOnRestore;
Value = 1;
}]
then,
NSArray *resultArray=[responseSrting JSONValue];
NSMuatbleArray *keyArray=[[NSMutableArray alloc] init];
NSMutableArray *valueArray=[[NSMutableArray alloc] init];
for(NSDictionary *dict in resultsArray){
[keyArray addObject:[dict objectForKey:#"Key"]];
[valueArray addObject:[dict objectForKey:#"Value"]];
}
then, all your keys are stored in keyArray and all your values are stored in valueArray

Loop through NSDictionary to create separate NSArrays

I have a large NSDictionary that I need to loop through and create separate NSArrays. Here are the contents:
(
{
id = {
text = "";
};
sub = {
text = " , ";
};
text = "";
"thumb_url" = {
text = "";
};
title = {
text = "2010-2011";
};
type = {
text = "title";
};
},
{
id = {
text = "76773";
};
sub = {
text = "December 13, 2010";
};
text = "";
"thumb_url" = {
text = "http://www.puc.edu/__data/assets/image/0004/76774/varieties/thumb.jpg";
};
title = {
text = "College Days - Fall 2010";
};
type = {
text = "gallery";
};
},
{
id = {
text = "";
};
sub = {
text = "";
};
text = "";
"thumb_url" = {
text = "";
};
title = {
text = "2009-2010";
};
type = {
text = "title";
};
},
{
id = {
text = "76302";
};
sub = {
text = "December 3, 2010";
};
text = "";
"thumb_url" = {
text = "http://www.puc.edu/__data/assets/image/0019/76303/varieties/thumb.jpg";
};
title = {
text = "Christmas Colloquy";
};
type = {
text = "gallery";
};
}
)
Each section has a type key, which I need to check. When it finds the title key, I need to add those to an array. Then the next sections that would use the gallery key needs to be in its own array until it finds another title key. Then the gallery keys after that into their own array.
I am using a UITableView section titles and content. So, the NSDictionary above should have one NSArray *titles; array, and two other arrays each containing the galleries that came after the title.
I have tried using a for loop but I just can't seem to get it right. Any ideas would be appreciated.
It's somewhat unclear by your log, but I'm guessing your NSDictionary has values of NSDictionary? If so:
NSMutableArray *titles = [NSMutableArray array];
// etc.
for (id key in sourceDictionary) {
NSDictionary *subDictionary = [sourceDictionary objectForKey:key];
if ([subDictionary objectForKey:#"type"] == #"title")
[titles addObject:[subDictionary objectForKey:#"title"]];
// etc.
}
Your question is a bit unclear... but this is how you would properly loop through an NSDictionary.
EDIT:
NSMutableDictionary *galleries = [NSMutableDictionary dictionary];
NSString *currentTitle;
for (id key in sourceDictionary) {
NSDictionary *subDictionary = [sourceDictionary objectForKey:key];
NSString *type = [subDictionary objectForKey:#"type"];
if (type == #"title") {
currentTitle = [subDictionary objectForKey:#"title"];
if ([galleries objectForKey:currentTitle] == nil)
[galleries setObject:[NSMutableArray array] forKey:currentTitle];
} else if (type == #"gallery" && currentTitle != nil)
[[galleries objectForKey:currentTitle] addObject:subDictionary];
}
After this loop, galleries will contain keys of type NSString (with values of the titles), and corresponding objects of type NSArray (with values of the gallery NSDictionarys). Hopefully this is what you were going for.
NSString *key;
for(key in someDictionary){
NSLog(#"Key: %#, Value %#", key, [someDictionary objectForKey: key]);
}
Modern Objective-C syntax:
NSMutableArray *things = [NSMutableArray array];
NSMutableArray *stuff = [NSMutableArray array];
NSMutableArray *bits = [NSMutableArray array];
[dictionaries enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[things addObject:[obj valueForKeyPath:#"thing"]];
[stuff addObject:[obj valueForKeyPath:#"enclosing_object.stuff"]];
[bits addObject:[obj valueForKeyPath:#"bits"]];
}];