NSDictionary within a NSDictionary - iphone

At the moment i've got the following code to get data from an xml file. This works so far
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"Placemark"]) {
placemarkData = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:#"name"])
[placemarkData addObject:string forKey:currentElement];
if ([currentElement isEqualToString:#"address"])
[placemarkData addObject:string forKey:currentElement];
if ([currentElement isEqualToString:#"coordinates"])
[placemarkData addObject:string forKey:currentElement];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"Placemark"]) {
[Placemarks addObject:[placemarkData copy]];
NSString *batsen = [placemarkData objectForKey:#"name"];
NSLog(#"adding story: %#", batsen);
}
}
This dictionary will be loaded into a array. Problem is that where this array got loaded in need to find the right entry in the array. I do it like this
TabbedCalculationAppDelegate *appDelegate = (TabbedCalculationAppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *jean = appDelegate.Placemarks;
NSDictionary *boekje = [jean objectAtIndex:1];
NSString *coordinaten = [boekje objectForKey:#"coordinates"];
NSString *naam = [boekje objectForKey:#"name"];
NSLog(#"poep: %#" , naam);
NSLog(#"wwhoppa: %#", coordinaten);
titel.text = coordinaten;
But since arrays works with index I can't find a way to get the right entry. To clarify, a user clicks in a mapview on an annotation. This annotation then gets the corresponding detailview. The detailview can check which annotation is clicked by the view.annotation.title;
So I actually need a dictionary in a dictionary with name as key in the root dictionary. Is this possible? and on what way I can implement this?
Is this a little bit clear? Else just ask!
Thnx guys

Yes, this is a good idea. Just pass the 'inner' dictionary as the object parameter to setObject:forKey: on the 'outer' dictionary. It'll just work. For example:
NSMutableDictionary *outer=[[NSMutableDictionary alloc] init];
NSDictionary *inner=[NSDictionary dictionaryWithObject:#"hello" forKey:#"world"];
[outer setObject:inner forKey:#"greetings"];

Related

this class is not key value coding-compliant for the key link [duplicate]

This question already has answers here:
Custom class NSObject not key value coding compliant [duplicate]
(4 answers)
Closed 9 years ago.
My app is crashing, any thoughts please? I am parsing the xml in my code, here is the code.
if i removed this line it works fine
[listItem setValue:currentElementValue forKey:elementName];
Thanks
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
if ([elementName isEqualToString:#"channel"]) {
NSLog(#"found channel");
app.listArray = [[NSMutableArray alloc]init];
}
else if([elementName isEqualToString:#"item"]){
listItem = [[NewsList alloc] init];
listItem.title = [attributeDict objectForKey:#"title"];
listItem.description = [attributeDict objectForKey:#"description"];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if (!currentElementValue) {
currentElementValue = [[NSMutableString alloc] initWithString:string];
}
else
[currentElementValue appendString:string];
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"channel"]) {
return;
}
if ([elementName isEqualToString:#"item"]) {
[app.listArray addObject:listItem];
listItem = nil;
}
else{
NSLog(#"element name = %#", elementName);
[listItem setValue:currentElementValue forKey:elementName];
}
currentElementValue = nil;
}
Your object listItem is of class NewsList. Since you get the error when you use setValue:forKey:, this class NewsList either has no property with name elementName and instance variable elementName or _elementName, or the setter method setElementName: has not been implemented.
Please check that you have set up your property correctly, e.g. using #property and #synthesize.

Xcode Get image url from rss feed

Newbie to Xcode and would be thrilled to get an answer to this question. I am trying to get the image url tag from a rss feed and add it to my custom table view cell. The other text I get fine.
This is the rss row:
<Item>
<title>this is a title</title>
<description>this is a description</description>
<link>http://www.something.com</link>
<pubDate>Fri, 09 Aug 2013</pubDate>
<enclosure type="image/jpg" url="http://www.ThisIsTheUrlIWant.com" />
</item>
This is part of my code without any image logic:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCellNews *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.titleLabel.text = [[feeds objectAtIndex:indexPath.row] objectForKey: #"title"];
cell.descriptionLabel.text = [[feeds objectAtIndex:indexPath.row] objectForKey: #"description"];
//set cell image here
return cell;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI: (NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
element = elementName;
if ([element isEqualToString:#"item"]) {
item = [[NSMutableDictionary alloc] init];
title = [[NSMutableString alloc] init];
link = [[NSMutableString alloc] init];
description = [[NSMutableString alloc] init];
//image stuff
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI: (NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"item"]) {
[item setObject:title forKey:#"title"];
[item setObject:link forKey:#"link"];
[item setObject:description forKey:#"description"];
//image stuff
[feeds addObject:[item copy]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([element isEqualToString:#"title"]) {
[title appendString:string];
} else if ([element isEqualToString:#"link"]) {
[link appendString:string];
} else if ([element isEqualToString:#"description"]) {
[ingress appendString:string];
}
//image stuff
}
Thanks
Try this:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"enclosure"]) {
NSString *units = [attributeDict objectForKey:#"url"];
}
}
Hope this helps.
First get the image URL from the attributes dictionary in the enclosure element inside the didStartElement method:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
//NSLog(#"Main View: didStartElement: %#\tstart", elementName);
element = elementName;
if ([element isEqualToString:#"item"]) {
item = [[NSMutableDictionary alloc] init];
title = [[NSMutableAttributedString alloc] init];
description = [[NSMutableAttributedString alloc] init];
link = [[NSMutableString alloc] init];
}
if ([element isEqualToString:#"enclosure"]) {
imageType = [attributeDict objectForKey:#"type"];
imageUrl = [attributeDict objectForKey:#"url"];
}
//NSLog(#"RSS Utility: didStartElement: %#", elementName);
}
Then add imageUrl to your item array inside the didEndElement method:
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"item"]) {
[item setObject:title forKey:#"title"];
[item setObject:link forKey:#"link"];
[item setObject:description forKey:#"description"];
[item setObject:imageType forKey:#"imageType"];
[item setObject:imageUrl forKey:#"imageUrl"];
[_feeds addObject:[item copy]];
}
}
This may not work for all rss feeds. I recommend you put NSLog statements inside the didStartElement to understand where the image url can be found:
NSLog(#"\nXML Parser:didStartElement:%#\n\t\t\tnameSpaceURI:%#\n\t\t\tqualifiedName:%#\n\t\t\tattributes:%#", elementName, namespaceURI, qName, attributeDict);

XMLParsing in IPhone for Login

I am following the below link to parse the xml for login page, http://yksoftware.blogspot.in/2010/04/iphone-programming-tutorial-xml-login.html
whenever i enter the fields of username and password, it displays login failed only even when i provide the correct username and password in the textfields.
In the following code when i keep the breakpoint in loginPressed method and check, it is not entering the for loop,
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
users = [[NSMutableArray alloc]init];
NSURL *xmlURL = [NSURL URLWithString:#"http://www.mailrail.net/sample.aspx?username=naresh&password=reddy"];
xmlParser = [[NSXMLParser alloc]initWithContentsOfURL:xmlURL];
[xmlParser setDelegate:self];
[xmlParser parse];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"User"]) {
item = [[NSMutableDictionary alloc] init];
currentUser =[[NSMutableString alloc] init];
currentPassword =[[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"User"]) {
[item setObject:currentUser forKey:#"username"];
[item setObject:currentPassword forKey:#"password"];
[users addObject:[item copy]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:#"username"]) {
[currentUser appendString:string];
}
if ([currentElement isEqualToString:#"password"]) {
[currentPassword appendString:string];
}
}
-(IBAction)loginPressed:(id)sender{
for (NSMutableDictionary *val in users) {
NSMutableString *usrname = [val objectForKey:#"username"];
NSLog(#"%#",usrname);
NSMutableString *psswrd = [val objectForKey:#"password"];
usrname=[usrname stringByReplacingOccurrencesOfString:#"\n" withString:#""];
usrname=[usrname stringByReplacingOccurrencesOfString:#"\t" withString:#""];
psswrd=[psswrd stringByReplacingOccurrencesOfString:#"\n" withString:#""];
psswrd=[psswrd stringByReplacingOccurrencesOfString:#"\t" withString:#""];
if([usrname isEqualToString:[txtUsername text]]&&[psswrd isEqualToString:[txtPassword text]]){
[lblLoginStatus setText:#"Login Successful!!"];
return;
}
}
[lblLoginStatus setText:#"login failed"];
return;
}
-(IBAction)returnClicked:(UITextField *)sender{
[sender resignFirstResponder];
}
-(IBAction)clickBackground:(id)sender{
[txtPassword resignFirstResponder];
[txtUsername resignFirstResponder];
}
and returns with login failed.
Thanks in advance.
You first need to solve the parsing how to parse some thing from xml using parser and then think for loging beacuse if you have made parser then it is easy to use login form. Below is the following tutorial for XML parsing it is detailed and help you can get help.
http://www.edumobile.org/iphone/iphone-programming-tutorials/parsing-an-xml-file/
hope this helps
Just check this
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"User"]) {
NSMutableDictionary *item = [[NSMutableDictionary alloc] init];
[item setValue:[attributeDict valueForKey:#"username"] forKey:#"username"];
[item setValue:[attributeDict valueForKey:#"password"] forKey:#"password"];
[users addObject:item];
}
}
please del other two delegates and check this

XML attribute pasrsing problem

i have to parse an xml and the link of that xml is
http://qasimshah.sitesled.com/schedule.xml
and may to parse is:
-(IBAction)autoLoginBtn{
NSString *url=[NSString stringWithFormat: #"http://qasimshah.sitesled.com/schedule.xml"];
[self parseXMLFileAtURL:url];
}
- (void)parseXMLFileAtURL:(NSString *)URL
{
xmlDataArray1 = [[NSMutableArray alloc] init];
//you must then convert the path to a proper NSURL or it won't work
NSURL *xmlURL = [NSURL URLWithString:URL];
// here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error
// this may be necessary only for the toolchain
NSXMLParser *rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[rssParser setDelegate:self];
// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
}
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
NSLog(#"Error on XML Parse: %#", [parseError localizedDescription] );
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
//NSLog(#"found this element: %#", elementName);
currentElement = [elementName copy];
if ([elementName isEqualToString:#"Sports"]) {
// clear out our story item caches...
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"Sport"]) {
[item setObject:currentTitle forKey:#"id"];
[xmlDataArray1 addObject:[item copy]];
NSLog(#"id: %#", currentTitle);
}
}
but when i try to get 'id' or name parser detect it but do not return me its value.
so how can i get its value?
You should get the attribute value in "attributeDict"
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
you are only referring element ...
Try this. You can get all the values like this.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"Sport"])
{
NSString *s = [NSString stringWithFormat:#"%#",elementName];
NSLog(#"%#",s);
NSString *s1 =[NSString stringWithFormat:#"%#",[attributeDict valueForKey:#"id"]];
NSLog(#"%#",s1);
NSString *s2 =[NSString stringWithFormat:#"%#",[attributeDict valueForKey:#"name"]];
NSLog(#"%#",s2);
NSString *s3 =[NSString stringWithFormat:#"%#",[attributeDict valueForKey:#"abbr"]];
NSLog(#"%#",s3);
}
}
In didStartElement: you're checking for "Sports" but in didEndElement: you're checking for "Sport"...

Using dictionaries with XML (iphone/iOs)

I want to parse data from a xml file. This is working so far, but I don't find the correct way to get data from the dictionary.
My parser looks as follows
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"Placemark"]) {
placemarkData = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:#"name"] || [currentElement isEqualToString:#"address"] || [currentElement isEqualToString:#"coordinates"])
[currentTitle appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"Placemark"]) {
[placemarkData setObject:currentTitle forKey:currentElement];
[Placemarks addObject:[placemarkData copy]];
NSLog(#"adding story: %#", currentElement);
}
As you can see. The data is stored in a dictionary, and this dictionary is store in an array. Only problem is... the key for dictionary is always coordinates. This look kinda logical to me... but I don't find the logic to implement it the right way. Can somebody have a look?
Thnx in advance!
When you fill a dictionary, you set objects for keys. To get an object from a dictionay, you need to have the key. And I think that is your problem.
To list the keys in your dictionary, you can use a keyEnumerator:
NSEnumerator *enumerator = [myDictionary keyEnumerator];
id key;
while ((key = [enumerator nextObject])) {
/* code that uses the returned key */
NSString *theElement = key;
NSLog(#"Element: %#", theElement);
}
With this code, you will list all the keys. To find the object with the key, you use [myDictionary objectForKey:key];. If you know the elements in your XML you can access them with this line.
I think the problem you are facing is because of the logic you used in
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"Placemark"]) {
placemarkData = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
}
}
method, i.e. allocating the placemarkData that will work fine if element Placemark is encountered first time but for the next iteration there will be problem, follow this idea and see the response on to the console, I am sure that you will find the solution.
come back if any doubt or query in that.