NSMutableArray and NSDictionary Error - iphone

I have one NSMutableArray called SubList that contains 262 element. Every object is a NSDictionary!
This code works like a charm!
for (NSDictionary *element in listSub){
[cell.textLabel setText:[element objectForKey:#"title"]];
}
But if I try to use use this code I get a SIGBART error!
NSDictionary * element = [listSub objectAtIndex:[indexPath row]];
[cell.textLabel setText:[element objectForKey:#"title"]];
So what's the problem?
*EDit the problem is at this line
NSDictionary * element = [listSub objectAtIndex:[indexPath row]];
and this is the description
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet objectAtIndex:]: unrecognized selector sent to instance 0x89a8d90'
Thanks
**Edit
This is the output of listSub!
listSub: {(
{
categories = (
{
id = "user/14761688561595773457/label/Web Programming";
label = "Web Programming";
}
);
firstitemmsec = 1265885595862;
id = "feed/http://feeds.feedburner.com/FamousBloggers";
sortid = A11327DE;
title = "Famous Bloggers";
},
{
categories = (
{
id = "user/14761688561595773457/label/Hacking";
label = Hacking;
}
);
firstitemmsec = 1241258413829;
htmlUrl = "http://backtrack-italia.blogspot.com/";
id = "feed/http://feeds2.feedburner.com/BackTrackItalia";
sortid = E8A04F76;
title = "Back Track Italia";
},
{
categories = (
{
id = "user/14761688561595773457/label/Hacking";
label = Hacking;
}
);
firstitemmsec = 1245376992188;
htmlUrl = "http://www.offensive-security.com";
id = "feed/http://www.offensive-security.com/blog/feed/";
sortid = 92F57555;
title = "BackTrack Information Security Distribution";
},
{
categories = (
{
id = "user/14761688561595773457/label/iOS Developer";
label = "iOS Developer";
}
);
firstitemmsec = 1296830392306;
htmlUrl = "http://amix.dk/Main/";
id = "feed/http://feeds.feedburner.com/amixdk";
sortid = 110C52C3;
title = "amix.dk blog";
},
{
categories = (
{
id = "user/14761688561595773457/label/Apple News";
label = "Apple News";
}
);
firstitemmsec = 1285261350202;
htmlUrl = "http://www.appletvhacks.net";
id = "feed/http://www.appletvhacks.net/feed/";
sortid = 81125D2E;
title = "Apple TV Hacks";
},
{
categories = (
{
id = "user/14761688561595773457/label/Apple News";
label = "Apple News";
}
);
firstitemmsec = 1293230300220;
htmlUrl = "http://www.appletvitalia.it";
id = "feed/http://www.appletvitalia.it/feed/";
sortid = 892FE61C;
title = "Apple Tv Italia";
},
{
categories = (
{
id = "user/14761688561595773457/label/Apple News";
label = "Apple News";
}
);
firstitemmsec = 1270115980935;
htmlUrl = "http://www.appleecious.com";
id = "feed/http://feeds2.feedburner.com/appleecious";
sortid = 00B5AFC2;
title = Appleecious;
},
{
categories = (
{
id = "user/14761688561595773457/label/Hacking";
label = Hacking;
}
);
firstitemmsec = 1258495136927;
htmlUrl = "http://www.rawseo.com/news";
id = "feed/http://www.rawseo.com/news/feed/";
sortid = D6766911;
title = "A blend of programming and seo";
},
{
categories = (
{
id = "user/14761688561595773457/label/Seo e Web Marketing";
label = "Seo e Web Marketing";
}
);
firstitemmsec = 1233684720758;
htmlUrl = "http://it-adsense.blogspot.com/";
id = "feed/http://it-adsense.blogspot.com/atom.xml";
sortid = 9FB570ED;
title = "AdSense Blog-Italiano";
},
{
categories = (
);
firstitemmsec = 1277627346000;
htmlUrl = "http://aext.net";
id = "feed/http://feeds.feedburner.com/aextnet";
sortid = 70800CFE;
title = "AEXT.NET NET MAGAZINE";
},
{
categories = (
);
firstitemmsec = 1217001547735;
htmlUrl = "http://www.alessandroscoscia.it";
id = "feed/http://feeds.feedburner.com/alessandroscoscia";
sortid = 51CB8E6E;
title = "Alessandro Scoscia";
},
{
categories = (
{
id = "user/14761688561595773457/label/iOS Developer";
label = "iOS Developer";
}
);
...
I'm sure that it isn't a NSSet.
Now I post the code that I'm using to populate my array.
NSError *error;
NSURLResponse *response;
NSData *dataReply = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];
NSString *string = [[NSString alloc] initWithData:dataReply encoding:NSASCIIStringEncoding];
NSLog(#"testing %#",string);
SBJsonParser *vol= [[SBJsonParser alloc]init];
if (string) {
NSArray *feeds = [vol objectWithString:string error:nil];
NSDictionary *results = [string JSONValue];
NSArray *subs = [results valueForKey:#"subscriptions"];
for (NSDictionary *iscrizione in subs){
[subscriptions addObject:iscrizione];
}
This is part of another class and also in this part of my code if i try to do something like this:
NSDictionary * element = [listSub objectAtIndex:0];
NSLog([element objectForKey:#"title"]);
I get the same error while if I try a loop like this
for (NSDictionary *element in listSub){
[cell.textLabel setText:[element objectForKey:#"title"]];
}
Everythings works fine without NSSet errors. This make me crazy!

The problem is probably that listSub was not properly retained and therefore released already. The memory is now re-used and the object at that address is now an __NSCFSet, which does not respond to objectAtIndex:.
Note that autoreleased objects returned by a convenience class method like [NSMutableArray arrayWithXXX] should be retained and only released when not needed anymore. The best way to be sure they are retained is to declare a #property(retain) NSArray *subList, #synthesize it and use self.subList in all cases except perhaps in dealloc.
Addition
It was suggested that the method that created subList returned a set and not an array. If that were the case, the simple loop at the begining of the answer would not function either. That is why I find it very unlikely that subList was originally an NSSet, and much more likely that the array was overreleased and dealloced and the memory re-used for the NSSet.
Please do what people who want to help you ask of you.
Add the line
NSLog(#"listSub: %#", listSub);
at the place where listSub is set and also right before the error line. Then look in the error log what it displays and tell us.

Have you tried:
[cell.textLabel setText:[element objectForKey:#"title"]];
What is that "lol"??

listSub isn't an array, it's an NSSet.

problem is here
[cell.textLabel setText:[NSString stringWithFormat:[element objectForKey:#"title"]]];
when you are call stringWithFormat then you need to give format in string literal form like this
[cell.textLabel setText:[NSString stringWithFormat:#"%#",[element objectForKey:#"title"]]];
or direct set the text with out calling stringWithFormat:
your array got released some where, so for solving the problem you need to call retain on tyour array at right place.

Just try this one.
NSDictionary * element = [listSub objectAtIndex:[indexPath row]];
[cell.textLabel setText:[NSString stringWithFormat:#"%#",[element objectForKey:#"title"]]];
Or try this as you have edit your question, Edit
NSDictionary *element = [[NSDictionary alloc] initWithDictionary:[listSub objectAtIndex:indexPath.row]];
[cell.textLabel setText:[element objectForKey:#"title"]];
[element release];

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

Sorting array of multiple dictionaries

My array contains three dictionaries per object of the array.
{
avg = {
avg1 = 50;
avg2 = 60;
};
posts = {
alcoholContent = 450;
name = "BBB";
origin = United States;
};
reviews = {
rev1 = "Test review 1";
rev2 = "Test review 2";
};
}
{
avg = {
avg1 = 30;
avg2 = 20;
};
posts = {
alcoholContent = 550;
name = "AAA";
origin = United States;
};
reviews = {
rev1 = "Test review 1";
rev2 = "Test review 2";
};
}
I want to sort array acceding by key "name" (of post dictionary).
How can I do it?
I tried normal sorting methods using sort descriptors, but did not work
Try sortUsingComparator:
[array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDictionary *dict1 = obj1;
NSDictionary *dict2 = obj2;
NSString *string1 = [[dict1 objectForKey:#"posts"] objectForKey:#"name"];
NSString *string2 = [[dict2 objectForKey:#"posts"] objectForKey:#"name"];
return [string1 compare:string2];
}];

How do I properly populate the UITableView NSArray from a NSDictionary created using JSONKit?

Sorry for the long question but that best summarizes what I am trying to do:
My JSON Looks like:
{
4e8cf1d6c7e24c063e000000 = {
"_id" = {
"$id" = 4e8cf1d6c7e24c063e000000;
};
author = faisal;
comments = (
{
author = adias;
comment = amazing;
},
{
author = nike;
comment = "I concur";
}
);
created = {
sec = 1317772800;
usec = 0;
};
text = "This is a random post";
title = "post # 1";
type = (
punjabi
);
};
4e91fd49c7e24cda74000000 = {
"_id" = {
"$id" = 4e91fd49c7e24cda74000000;
};
author = draper;
comments = (
{
author = adias;
comment = "amazing again";
}
);
created = {
sec = 1318118400;
usec = 0;
};
text = "This is a random post again";
title = "post # 2";
type = (
punjabi
);
};
}
What I would like to do is to ultimately have a UTTableview with each row having a title (text from above JSON):
This is the code I have so far:
NSString *responseString = [request responseString];
NSDictionary *resultsDictionary = [responseString objectFromJSONString];
How do I put everything in an array for the UITableView? Again I am just a little rusty as I can swear I have done that before.
If you don't need the keys then you can convert it to an array by using allValues, e.g.:
NSArray *values = [resultsDictionary allValues];
Does your JSON really parse to an NSDictionary, or is this an NSArray containing NSDictionary instances? If the latter, then isn't it just something like:
NSString *textForCell = [[resultsArray objectAtIndex:row] valueForKey:#"title"];

Trouble reading JSON object using Obj-C

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

Open specific trail with a url scheme from NSDictionary

I am using TouchJSON to retrieve the JSON response from http://enbr.co.cc/TrailsApp/shops.php. In my app I use this code to handle a url scheme.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
if (!url) {
return NO;
}
NSString *urlString = [url absoluteString];
NSString *urlStringDecoded = [urlString stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSArray *list = [urlStringDecoded componentsSeparatedByString:#"="];
NSString *urlPrefix = [list objectAtIndex:0];
NSString *name = [list objectAtIndex:1];
if ([urlPrefix isEqualToString:#"tridetrails://opentrail?name"]) {
TrailViewController *trailViewController = [[TrailViewController alloc] initWithNibName:#"TrailViewController" bundle:[NSBundle mainBundle]];
trailViewController.trailToGoto = name;
[self.navigationController pushViewController:trailViewController animated:YES];
[trailViewController release];
}
if ([urlPrefix isEqualToString:#"tridetrails://openshop?name"]) {
ShopViewController *shopViewController = [[ShopViewController alloc] initWithNibName:#"ShopViewController" bundle:[NSBundle mainBundle]];
shopViewController.shopToGoto = name;
[self.navigationController pushViewController:shopViewController animated:YES];
[shopViewController release];
}
return YES;
}
How can I push the correct entry from my NSDictionary created from the JSON to the ShopViewController based on the NSString name? Here is my dictionary printed out by NSLog with NSLog(#"%#", myObj);. Thanks in advance.
{
shops = (
{
blurb = "Bootdoctors blurb";
image = bootdoctorslogo;
locations = "Mountain Village";
motto = "Bootdoctors shop motto";
name = Bootdoctors;
},
{
blurb = "Easy Rider blurb";
image = easyriderlogo;
locations = Telluride;
motto = "Easy Rider shop motto";
name = "Easy Rider";
},
{
blurb = "Paragon Ski & Sport blurb";
image = paragonskiandsportlogo;
locations = Telluride;
motto = "Paragon shop motto";
name = "Paragon Ski & Sport";
},
{
blurb = "Telluride Sports blurb";
image = telluridesportslogo;
locations = "Telluride and Mountain Village";
motto = "Telluride Sports shop motto";
name = "Telluride Sports";
}
);
}
You probably need to give a bit more information about what you are trying to do. For instance you don't say how you retrieve the dictionary containing the details of all the shops and how ShopViewController has access to this dictionary. But selecting one shop by name from the dictionary can be done with something like this:
NSDictionary *jsonResponse; // You don't say how the ShopViewController has access to
// the response so let's just assume a local variable here.
NSDictionary *foundShop = nil; // This will be selected shop after the search below
NSArray *shops = [jsonResponse objectForKey:#'shops'];
for (NSDictionary *shop in shops) {
if ([shop objectForKey:#'name'] isEqualToString:self.shopToGoto]) {
foundShop = shop;
break;
}
}
if (foundShop) {
// Do something with the dictionary keys and values in foundShop
}
else {
// Error condition - shop with required name is not present
// Handle error
}
You could use a NSPredicate to select the shop(s) you are looking for:
NSString* shopName = ...;
NSArray* shops = ...; // this is your JSON-produced array of NSDictionary Shop objects
NSPredicate* predicate = [NSPredicate predicateWithFormat: #"name == '%#'", shopName ];
NSArray* matchingShops = [shops filteredArrayUsingPredicate: predicate];
NSDictionary* firstMatchingShop = [matchingShops objectAtIndex: 0];