How I can iterate and get all values in a NSDictionary? - iphone

I have a problem.
I am using the XMLReader class to get a NSDictionary and everything works fine. But i can't to get the values of the atributes of my productData element.
Specifically, I have the following NSDictionary:
{
response = {
products = {
productsData = (
{
alias = "Product 1";
id = 01;
price = "10";
},
{
alias = "Product 2";
id = 02;
price = "20";
},
{
alias = "Product 3";
id = 03;
price = "30";
});
};
};
}
I used this code to create de NSDictionary:
NSDictionary *dictionary = [XMLReader dictionaryForXMLData:responseData error:&parseError];
and responseData contains:
<application>
<products>
<productData>
<id>01</id>
<price>10</price>
<alias>Product 1</alias>
</productData>
<productData>
<id>02</id>
<price>20</price>
<alias>Product 2</alias>
</productData>
<productData>
<id>02</id>
<price>20</price>
<alias>Product 3</alias>
</productData>
</products>
</application>
Then, i don't know how get the values of each productData like id, price and alias...
Anybody know how to do it??
Thanks and please forgive my bad english !

NSArray* keys = [theDict allKeys];
for(NSString* key in keys) {
id obj = [theDict objectForKey:key];
// do what needed with obj
}
you could try something like this :
NSArray* keys = [theDict allKeys];
for(NSString* key in keys) {
if ([key isEqualToString:#"product"]) {
NSArray* arr = [theDict objectForKey:key];
// do what needed with arr
}
}

There is a method on NSDictionary - -allValueswhich returns a new array containing the dictionary’s values. Maybe that will help.

Starting with
NSDictionary *dictionary = [XMLReader dictionaryForXMLData:responseData error:&parseError];
you can do something like this:
NSDictionary *application = [dictionary objectForKey:#"application"];
if ([[application objectForKey:#"products"] isKindOfClass [NSArray class]]) {
NSArray *products = [application objectForKey:#"products"];
for (NSDictionary *aProduct in products) {
// do something with the contents of the aProduct dictionary
}
else if {[[application objectForKey:#"products"] isKindOfClass [NSDictionary class]]) {
// you will have to see what the returned results look like if there is only one product
// that is not in an array, but something along these lines may be necessary
// to get to a single product dictionary that is returned
}
I have had a case similar to this (parsing JSON) where an array was not returned for a signle value, so the result had to be checked for both an array (of product dictionaries in your case) or a single NSDictionary (the product dictionary in your case).

Related

Array not get data for particular key

Response array like this
NewDataSet = {
Table = (
{
City = {
text = "\nThiruvananthapuram";
};
Country = {
text = "\n\nIndia";
};
text = "\n";
},
{
City = {
text = "\nVellore";
};
Country = {
text = "\n\nIndia";
};
text = "\n";
}
);
text = "\n";
I have write this code..
xmlDictionary = [XMLReader dictionaryForXMLString:xmlResultString error:nil];
NSLog(#"%#",xmlDictionary);
NSLog(#"%#",xmlDictionary);
NSArray * responseArr = xmlDictionary[#"NewDataSet"];
NSLog(#"%#",responseArr);
for(NSDictionary * dic in responseArr)
{
NSLog(#"%#",dic);
//[array1 addObject:[dic valueForKey:#"City"]];
[array1 addObject:[[dic valueForKey:#"City"] valueForKey:#"text"]];
}
but not get the data. in array1. please help me out this thanks in advance.
Problem is i will not get the value in NSDictionary.
Error log is
this class is not key value coding-compliant for the key City.'
I got my Solution problem is i will not get the direct City key. Because City key is under the NewDataSet & Table
so first you go to the NewDataSet and then Table key then finally you get the City key.
Now get array data from Dictionary Like
NSArray * City=[[NSArray alloc]init];
City=[[[xmlDictionary valueForKey:#"NewDataSet"] valueForKey:#"Table"] valueForKey:#"City"];
NSLog(#"%#",City);
pass multiple keys inside key this is the solution.
It seems you haven't allocated array1 anywhere,
Your solution goes here:
array1 = [[NSMutableArray alloc]init];
for(NSDictionary * dic in responseArr)
{
[array1 addObject:[dic valueForKey:#"City"]];
}
NSLog(#"array1 >> %#",array1);
If you have already allocated array1, then please try to log the value for [dic valueForKey:#"City"].
try this code...
for(int i =0;i<[responseArr count];i++)
{
NSString *str = [[responseArr objectAtIndex:i] valueForKey:#"City"];
[array1 addObject:str];
}
let me know it is working or not!!!
Happy Coding!!!
array1 = [[NSMutableArray alloc]init];
for(NSDictionary * dic in responseArr)
{
[array1 addObject:[dic objectForKey:#"City"]];
}
NSLog(#"array1 >> %#",array1);
Try this

NSDictionary flatten hierarchy

I've got an NSDictionary object like this:
dictionary: {
data = {
"access_token" = "xxx";
"expires_in" = 00;
"refresh_token" = "yyy";
"token_type" = bearer;
};
}
How can I flatten it so that I remove the 'data' object? Is there a quick way to do that?
So the output should look like this:
dictionary: {
"access_token" = "xxx";
"expires_in" = 00;
"refresh_token" = "yyy";
"token_type" = bearer;
};
NSDictionary *dataDict = [mainDict objectForKey:#"data"];
flat dict in your example:
//grab data
NSDictionary *data = [yourDict objectForKey:#"data"];
assert(data != nil);
NSDictionary *flatDict = data; //OR data.copy // OR [NSDictionary dictionaryWithDictionary:data];
It doesn't look like "data" is an NSDictionary. Try
id what = [dict objectForKey : #"data"];
NSLog(#"%#", [what class]);
What does it say?
using recursive function, the only problem with this method is it will replace the old data if key happened to be the same in the nested dictionary
- (NSDictionary *)flattedDictionary{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *key in self.allKeys) {
id object = [self objectForKey:key];
if (![object isKindOfClass:[NSDictionary class]] && !isNull(object)) {
[dict setObject:object
forKey:key];
} else if ([object isKindOfClass:[NSDictionary class]]){
[dict addEntriesFromDictionary:[object flattedDictionary]];
}
}
return [NSDictionary dictionaryWithDictionary:dict];
}

How to create an array with particular item from a dictionary?

I have an application in which i am having the details of the members as a dictionary.i want to add an array with particular object from the dictionary.The response i am having is like this,
{
500 = {
name = baddd;
status = "<null>";
};
511 = {
name = abyj;
status = "Hi all...:-)";
};
512 = {
name = abyk;
status = fdffd;
};
}
I want to create an array with the results of name only.i have tried like this
for(int i=0;i<=self.currentChannel.memberCount;i++)
{
NSString *name=[NSString stringWithFormat:#"%#",[self.currentChannel.members objectForKey:#"name"]] ;
NSLog(#"%#",name);
[searchfriendarray addObject:name];
}
NSLog(#"%#",searchfriendarray);
but the value added is null. can anybody help me ?
Traverse objectEnumerator to get the values (inner dictionaries). Then just add the value of "name" to the resulting array. Example (assuming the dictionary is named d):
NSDictionary* d = ...
NSMutableArray* array = [NSMutableArray arrayWithCapacity:d.count];
for(NSDictionary* member in d.objectEnumerator) {
[array addObject:[member objectForKey:#"name"]];
}
Krumelur was faster than me ;) He is right by saing that you should traverse the dictionary values first. In your implementation you don't reference your counter variable i somewhere, so the NSString name is the same in each iteration.
This may help you..
// here you can get Array of Dictionary First
NSArray *arr = [[NSArray alloc] initWithContentsOfFile:#""]; // get array first from your response
NSDictionary *temp = [[NSDictionary alloc] initWithDictionary:self.currentChannel.members];
for(int i=0;i<=self.currentChannel.memberCount;i++)
{
NSDictionary *temp = [arr objectAtIndex:i];
NSString *name=[NSString stringWithFormat:#"%#",[temp objectForKey:#"name"]] ;
NSLog(#"%#",name);
[searchfriendarray addObject:name];
}
NSLog(#"%#",searchfriendarray);
Thanks.

Objective-C for in loop nested NSDictionaries

I've got this data I get from an XML feed and parse as NSDictionaries. The data structure is like this:
item = {
address = {
text = "1 Union Street";
};
data = {
text = "Hello.";
};
event_date = {
text = "2012-02-27";
};
event_type = {
text = pubQuiz;
};
latitude = {
text = "57.144994";
};
longitude = {
text = "-2.10143170000003";
};
name = {
text = "Mobile Tester";
};
picture = {
text = "public://pictures/event_default.png";
};
time = {
text = "23.00";
};
vname = {
text = Test;
};
}
//More items
Each sub-section, ie, address, data, event_date etc are all NSDictonaries.
I would like to iterate through the whole collection and grab the "text" inside each of the sections to create an array of "items" with these properties. I've tried using the for..in loop structure in Objective-C but haven't had any success so far. Has anyone got a few pointers? I'm happy to read through any good tutorials or examples on how to traverse nested NSDictionaries.
EDIT:
Alright so, after parsing the XML I get that structure up there. What I would like to do is traverse the "item" structure to extract the "text" fields of all the inner dictionaries - something like this:
foreach(item in array of dictionaries) {
myItem.address = item.address.text;
myItem.data = item.data.text;
...
}
And so on. I hope this makes it a little clearer.
So, the part where I'm stuck is where I want to set the properties of the item while traversing the NSDictionaries. This is what I have so far:
for(NSDictionary *item in self.eventsArray) {
for (NSDictionary *key in [item allKeys]) {
NSLog(#"%#", key);
id value = [item objectForKey:key];
if ([value isKindOfClass:[NSDictionary class]]) {
NSDictionary* newDict = (NSDictionary*)value;
for (NSString *subKey in [newDict allKeys]) {
NSLog(#"%#", [newDict objectForKey:subKey]);
}
}
}
}
Which outputs:
address
1 Union Street
data
Hello.
...
I'm just not sure how to select the proper attribute in the object I'm creating to set the required property, if that makes any sense?
You can create a new dictionary called items from the original one (called here dictionaries) :
NSMutableDictionary *items = [[NSMutableDictionary alloc] init];
for (NSDictionary *dict in dictionaries)
{
[items setValue:[dict objectForKey:#"text"] forKey:[dict description]];
}
It will create the following dictionary:
item = {
address = "1 Union Street",
data = "Hello.",
....
}
To get the items I did the following:
id eventsArray = [[[[XMLReader dictionaryForXMLData:responseData error:&parseError] objectForKey:#"root"] objectForKey:#"events"] objectForKey:#"event"];
if([eventsArray isKindOfClass:[NSDictionary class]])
{
//there's only one item in the XML, so there's only an NSDictionary created.
for(NSString *item in (NSDictionary*)eventsArray)
{
//check what each item is and deal with it accordingly
}
}
else
{
//There's more than one item in the XML, an array is created
for(NSDictionary *item in (NSArray*)eventsArray)
{
for (NSString *key in [item allKeys])
{
//check what value key is and deal with it accordingly
}
}
}
And that allows me to access all elements.

NSdictionary sorting problem

I have an array of NSDictionary.
NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:bothUserName forKeys:bothUID]; // here array "bothUserName" and "bothUID" is an NSArray type
[dictionary keysSortedByValueUsingSelector:#selector(compare:)];
NSLog(#" dictionary objects %#",dictionary);
I am getting an output like this.
dictionary objects {
14172368 = webtickle;
271882407 = electrodealio;
314125883 = Coral5mz;
316212228 = ajaysinghHF2;
316348693 = Caroline99a;
43944597 = WorldStuffer;
}
but I want to have output like this.
dictionary objects {
316212228 = ajaysinghHF2;
316348693 = Caroline99a;
314125883 = Coral5mz;
271882407 = electrodealio;
14172368 = webtickle;
43944597 = WorldStuffer;
}
Thanks in advance.
keysSortedByValueUsingSelector returns a sorted array containing dictionary's keys, you have to use this returned array to retrieve the associated objects:
NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:bothUserName forKeys:bothUID];
NSArray *sortedKeys = [dictionary keysSortedByValueUsingSelector:#selector(compare:)];
for (NSString *key in sortedKeys) {
NSLog(#"%#: %#", key, [dictionary objectForKey:key]);
}