I syncing the data on my website to my app, I'm using NSXMLParser to do this. The problem is I have all the fields on my database defined as Strings. The sync process works fine when everything is a string, but this is causing me heartache further down the line when I try and use this data for other purposes.
Can anyone help me with defining my fields with the correct data types for the sync process, code below:
.m
// Array for WORKOUT.
NSMutableString *currentID, *currentUserID, *currentWalkID, *currentDate, *currentDistance, *currentRepeats, *currentType, *currentIntensity,
*currentComments, *currentTime, *currentWeight, *currentHeight;
I know its something to do with this NSMutableString, obviously everything is defined as a string.
.h
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
currentElement = [elementName copy];
// Check for the WORKOUT details in the XML feed.
if ([elementName isEqualToString:#"workout"])
{
// clear out our workout item caches...
item = [[NSMutableDictionary alloc] init];
currentID = [[NSMutableString alloc] init];
currentUserID = [[NSMutableString alloc] init];
currentWalkID = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentDistance = [[NSMutableString alloc] init];
currentRepeats = [[NSMutableString alloc] init];
currentType = [[NSMutableString alloc] init];
currentIntensity = [[NSMutableString alloc] init];
currentComments = [[NSMutableString alloc] init];
currentTime = [[NSMutableString alloc] init];
currentWeight = [[NSMutableString alloc] init];
currentHeight = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"workout"])
{
Workout *newWorkout = [NSEntityDescription insertNewObjectForEntityForName:#"Workout" inManagedObjectContext: self.managedObjectContext];
// save values to an item, then store that item into the array...
[item setObject:currentID forKey:#"workout_id"];
[item setObject:currentUserID forKey:#"workout_user_id"];
[item setObject:currentWalkID forKey:#"workout_walk_id"];
[item setObject:currentDate forKey:#"workout_date"];
[item setObject:currentDistance forKey:#"workout_distance"];
[item setObject:currentRepeats forKey:#"workout_repeats"];
[item setObject:currentType forKey:#"workout_type"];
[item setObject:currentIntensity forKey:#"workout_intensity"];
[item setObject:currentComments forKey:#"workout_comments"];
[item setObject:currentTime forKey:#"workout_time"];
[item setObject:currentWeight forKey:#"workout_weight"];
[item setObject:currentHeight forKey:#"workout_height"];
newWorkout.workout_id = currentID;
newWorkout.workout_user_id = currentUserID;
newWorkout.workout_walk_id = currentWalkID;
newWorkout.workout_date = currentDate;
newWorkout.workout_distance = currentDistance;
newWorkout.workout_repeats = currentRepeats;
newWorkout.workout_type = currentType;
newWorkout.workout_intensity = currentIntensity;
newWorkout.workout_comments = currentComments;
newWorkout.workout_time = currentTime;
newWorkout.workout_weight = currentWeight;
newWorkout.workout_height = currentHeight;
[self.workoutArray addObject:newWorkout];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
// save the characters for the current item...
if ([currentElement isEqualToString:#"workout_id"]) {
[currentID appendString:string];
} else if ([currentElement isEqualToString:#"workout_user_id"]) {
[currentUserID appendString:string];
} else if ([currentElement isEqualToString:#"workout_walk_id"]) {
[currentWalkID appendString:string];
} else if ([currentElement isEqualToString:#"workout_date"]) {
[currentDate appendString:string];
} else if ([currentElement isEqualToString:#"workout_distance"]) {
[currentDistance appendString:string];
} else if ([currentElement isEqualToString:#"workout_repeats"]) {
[currentRepeats appendString:string];
} else if ([currentElement isEqualToString:#"workout_type"]) {
[currentType appendString:string];
} else if ([currentElement isEqualToString:#"workout_intensity"]) {
[currentIntensity appendString:string];
} else if ([currentElement isEqualToString:#"workout_comments"]) {
[currentComments appendString:string];
} else if ([currentElement isEqualToString:#"workout_time"]) {
[currentTime appendString:string];
} else if ([currentElement isEqualToString:#"workout_weight"]) {
[currentWeight appendString:string];
} else if ([currentElement isEqualToString:#"workout_height"]) {
[currentHeight appendString:string];
}
XML can only carry strings. Wheather it's an element's inner text or the value of an attribute, in the end everything is just a string.
If you want to send anything other via XML, the sending side has to encode it in a string and the receiving side has to decode the string. For that to work both sides have to agree on a format, for Example for an Integer value one possibility is to encode 125 as "125", or a float 2.5 as "2.5". If you are using this format for your numbers you can decode them by using the integerValue and floatValue of NSString.
float test = [#"2.5" floatValue];
There are some standard formats defined in xsd, that you could use, but that will not help you decode them, if you don't have a parser that does this for you. (NSXMLParser is no such)
If you are using other Formats look at NSScanner. For dates and time you would like to look at NSDateFormatter.
If you need help converting please post the format you are using, that is an excerpt of your XML.
Related
I'm downloading Google weather through the API. I'm having trouble parsing.
Using NSXMLParserDelegate, it finds the element "forecast_conditions," but I cannot seem to extract it's content. The parsers seems to think "high" and "low" etc are separate elements.
This is an element I'm try to parse:
<forecast_conditions><day_of_week data="Sun"/><low data="20"/><high data="38"/><icon data="/ig/images/weather/sunny.gif"/><condition data="Clear"/></forecast_conditions>
I'm surprised ...
`- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(#"foundCharacters string: %#",string);
}`
doesn't return anything either. I thought this parsed the contents of an element
Help appreciated.
It turns out the parser creates the "attributeDict" dictionary automatically. Cycling through the elementNames, you only need to call [attributeDict objectForKey:#"data"]. Example below.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
// current conditions
if ([elementName isEqualToString:#"current_conditions"]) {
currentConditions = [[NSMutableString alloc] init];
temp_f = [[NSMutableString alloc] init];
temp_c = [[NSMutableString alloc] init];
humidity = [[NSMutableString alloc] init];
currentIcon = [[NSMutableString alloc] init];
wind_condition = [[NSMutableString alloc] init];
}
if ([elementName isEqualToString:#"condition"]) {
[currentConditions appendString:[attributeDict objectForKey:#"data"]];
}
if ([elementName isEqualToString:#"temp_f"]) {
[temp_f appendString:[attributeDict objectForKey:#"data"]];
}
if ([elementName isEqualToString:#"temp_c"]) {
[temp_c appendString:[attributeDict objectForKey:#"data"]];
}
if ([elementName isEqualToString:#"humidity"]) {
[humidity appendString:[attributeDict objectForKey:#"data"]];
}
if ([elementName isEqualToString:#"currentIcon"]) {
[currentIcon appendString:[attributeDict objectForKey:#"data"]];
}
if ([elementName isEqualToString:#"wind_condition"]) {
[wind_condition appendString:[attributeDict objectForKey:#"data"]];
}
I am trying to extract the title from this xml:
<entry>
...
<title type="html">Some title</title>
<published>2011-02-07T00:04:16Z</published>
<updated>2011-02-07T00:04:16Z</updated>
...
</entry>
in the NSXMLParsing's didStartElement code:
if ([elementName isEqualToString:#"entry"])
{
item = [[NSMutableDictionary alloc] init];
}
if([elementName isEqualToString:#"title"])
{
currentElement = [elementName copy];
currentTitle = [[NSMutableString alloc] init];
}
in foundCharacters:
if ([currentElement isEqualToString:#"title"])
{
[currentTitle appendString:string];
}
in didEndElement:
if ([elementName isEqualToString:#"entry"])
{
[item setObject:currentTitle forKey:#"title"];
[currentElement release];
currentElement = nil;
[item release];
item = nil;
}
The problem is that for some reason when it gets to the didEndElement the currentTitle has got the three node's content, so its:
Some
title2011-02-07T00:04:16Z2011-02-07T00:04:16Z
I don't get why its picking up the published and updated node and appending them to the title string.
You set currentElement to #"title" in didStartElement: but you never unset it. The first element in this particular XML file is title, so you set currentElement and for every foundCharacters: thereafter you append them. Change didStartElement: to:
currentElement = [elementName copy];
if ([elementName isEqualToString:#"entry"])
{
item = [[NSMutableDictionary alloc] init];
}
if([elementName isEqualToString:#"title"])
{
currentTitle = [[NSMutableString alloc] init];
}
You have to add to didEndElement:
if ([elementName isEqualToString:#"title"])
{
[currentElement release];
currentElement = nil;
}
define
NSMutableString *strFoundCharacters; in class method set property and synthesize it.
then in
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *) string {
NSString *strAppend = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([strAppend length] > 0) {
[self.strFoundCharacters appendString:string];
}
}
make nil to strfoundcharacter in
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"title"] ) {
self.currentTitle = self.strFoundCharacters;
}
[self.strFoundCharacters setString:#""];
}
i think it will work
I've been very unfortunate with my programming. I am still rather new to Objective-C, but I am trying to learn as quickly as possible.
I need to complete an RSS Reader for iPhones application, a relatively simple one which parses the rss feed, displays it in a navigation-table view and when you click on an article you are taken to a main page.
Unfortunately, I am having difficulty with the parsing aspect. Currently, the program downloads all the articles, but I would like to display it in lists of 10, along with a next button at the bottom. Once the next button is clicked, the parsing continues and the next 10 are on display.
I am sorry but I cannot show you the code I am using at the moment as I am on my home computer and the project is on the office mac. If anyone could give me some Ideas i would be most grateful. I have tried a number of methods (making an additional array to act as an article counter so I could record which article is which for which list, for example) but i keep running into roadblocks as I just dont know how to use the program well enough to do that.
Please, I am in a lot of need! Thank you.
(This is me again)
I am sorry if this is rather vague, but I believe I can give sample code. I am trying to make it that the program pauses parsing after 10 articles are parsed, displays those 10, then continues parsing and displaying another 10 if a next button is pressed.
In the parser.m, i have written:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"item"]) {
item = [[NSMutableDictionary alloc] init];
self.currentTitle = [[NSMutableString alloc] init];
self.currentDate = [[NSMutableString alloc] init];
self.currentSummary = [[NSMutableString alloc] init];
self.currentLink = [[NSMutableString alloc] init];
self.currentImage = [[NSMutableString alloc] init];
}//IF END
//podcast url is an attribute of the element enclosure
if ([currentElement isEqualToString:#"enclosure"]) {
[currentImage appendString:[attributeDict objectForKey:#"url"]];
NSLog(#"Image = %#", currentImage);
}//IF END
else if([currentElement isEqualToString:#"img"]){
[currentImage appendString:[attributeDict objectForKey:#"src"]];
NSLog(#"Image = %#", currentImage);
}//ELSE IF END
}
I also have the didEndElement and Found characters section:
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"item"]) {
[item setObject:self.currentTitle forKey:#"title"];
[item setObject:self.currentLink forKey:#"link"];
[item setObject:self.currentSummary forKey:#"summary"];
[item setObject:self.currentImage forKey:#"image"];
// Parse date here
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:#"EEE, d MMM yyyy"]; // Thu, 18 Jun 2010 04:48:09 -0700
NSLog(#"FC date1 = %#", self.currentDate);
NSDate *date = [[NSDate alloc] init];
date = [dateFormatter dateFromString:currentDate];
NSLog(#"FC date2 = %#", date);
[item setObject:self.currentDate forKey:#"date"];
//[item setObject:date forKey:#"date"];
[date release];
[items addObject:[item copy]];
NSLog(#"Item details = %#", items);
[count addObject:[item objectForKey:#"title"]];
NSLog(#"count = %#", count);
}//IF END
}
I have also been having some issues with formatting the date, but thats a minor issue.
also:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:#"title"]) {
[self.currentTitle appendString:string];
} else if ([currentElement isEqualToString:#"link"]) {
[self.currentLink appendString:string];
} else if ([currentElement isEqualToString:#"image"]) {
[self.currentImage appendString:string];
} else if ([currentElement isEqualToString:#"description"]) {
[self.currentSummary appendString:string];
} else if ([currentElement isEqualToString:#"pubDate"]) {
[self.currentDate appendString:string];
NSCharacterSet* charsToTrim = [NSCharacterSet characterSetWithCharactersInString:#" \n"];
[self.currentDate setString: [self.currentDate stringByTrimmingCharactersInSet: charsToTrim]];
}//IF-ELSE-IF END
}
I would be most grateful if someone could give me a tip on what to do to pause the program...or allow me to parse in groups of 10...I am at a loss ;_;
Thank you for your time.
i try to parse within my iPhone SDK 4
http://de.news.search.yahoo.com/news/rss?p=iphone&ei=UTF-8&fl=0&x=wrt
there are some german umlaute
<description><![CDATA[Mehr als die Hälfte der Belegschaft des weltweit größten]]></description>
As I read in another forum as long they are wrapped in CDATA it should be fine.
But in the moment the parser found the element "description"
he breaks with:
error parsing XML: Unable to download story feed from web site (Error code 9 ) http://de.news.search.yahoo.com/news/rss?p=iphone&ei=UTF-8&fl=0&x=wrt
The english feeds works fine !? So its something with this umlaute, but what can i do?
greets
chris
JUST FOR UNDERSTANDING .. HERE MY WHOLE PARSER
- (void)parseXMLFileAtURL:(NSString *)URL {
aktuelleUrl = URL;
stories = [[NSMutableArray alloc] init];
NSURL *xmlURL = [NSURL URLWithString:aktuelleUrl];
// 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
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)parserDidStartDocument:(NSXMLParser *)parser{
//NSLog(#"found file and started parsing");
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:#"Unable to download story feed from web site (Error code %i ) %#", [parseError code], aktuelleUrl];
NSLog(#"error parsing XML: %#", errorString);
}
- (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:#"channel"]) {
channel1item2 = 1;
// clear out our story item caches...
// item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
// currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
}
if ([elementName isEqualToString:#"item"]) {
channel1item2 = 2;
// clear out our story item caches...
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
currentEncoded = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
//NSLog(#"ended element: %# c1i2: %i", elementName, channel1item2);
if (channel1item2 == 1) {
if (![currentTitle isEqualToString:#""]) { aCurrentTitle = currentTitle; }
if (![currentLink isEqualToString:#""]) { aCurrentLink = currentLink; }
if (![currentSummary isEqualToString:#""]) {aCurrentSummary = currentSummary; }
}
else if ([elementName isEqualToString:#"item"]) {
[item setObject:currentTitle forKey:#"title"];
[item setObject:currentLink forKey:#"link"];
[item setObject:currentSummary forKey:#"summary"];
[item setObject:currentDate forKey:#"date"];
[item setObject:currentEncoded forKey:#"content:encoded"];
[stories addObject:[item copy]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
//NSLog(#"found characters: %#", string);
// save the characters for the current item...
if ([currentElement isEqualToString:#"title"]) {
[currentTitle appendString:string];
} else if ([currentElement isEqualToString:#"link"]) {
[currentLink appendString:string];
//NSLog(#"parselink '%#'",string);
} else if ([currentElement isEqualToString:#"description"]) {
[currentSummary appendString:string];
} else if ([currentElement isEqualToString:#"pubDate"]) {
[currentDate appendString:string];
} else if ([currentElement isEqualToString:#"content:encoded"]) {
[currentEncoded appendString:string];
}
else if ([currentElement isEqualToString:#"media:content"]) {
//NSLog(#"mediacontent %#",string);
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
// NSLog(#"all done!");
//NSLog(#"stories array has %d items", [stories count]);
}
Perhaps look into -stringWithContentsOfURL:usedEncoding:error: to download the XML:
NSError *error = nil;
NSStringEncoding encoding;
NSString *xmlFeedStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://de.news.search.yahoo.com/news/rss?p=iphone&ei=UTF-8&fl=0&x=wrt"] usedEncoding:&encoding error:&error];
NSXMLParser *rssParser = [[NSXMLParser alloc] initWithData:[xmlFeedStr dataUsingEncoding:encoding allowLossyConversion:YES]];
...
[rssParser release];
From the documentation:
NSXMLParserInvalidCharacterError = 9
Perhaps the document is not really encoded in UTF-8?
Now I solved it different. Wrote my own XML parser just simple for my needs and with the following routine, i found in some forum, i encode the xml string. Also I marked the answer above as 'accepted' as it lead me into the right direction.
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)s {
[resultString appendString:s];
}
- (NSString*)convertEntiesInString:(NSString*)s {
resultString = [[NSMutableString alloc] init];
if(s == nil) {
//NSLog(#"ERROR : Parameter string is nil");
}
NSString* xmlStr = [NSString stringWithFormat:#"<d>%#</d>", s];
NSData *data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSXMLParser* xmlParse = [[NSXMLParser alloc] initWithData:data];
[xmlParse setDelegate:self];
[xmlParse parse];
NSString* returnStr = [[NSString alloc] initWithFormat:#"%#",resultString];
return returnStr;
}
objectsResultStr = [self convertEntiesInString:orgString]];
I am trying to parse an RSS XML feed. I have figured out how to parse what's in the tags for the individual stories, but I cannot figure out how to get the name of the entire feed (for example "CNN's News Feed"). I think it's in and I've tried a ton of things but I can't figure it out. Below is part of my parsing code that I think what seemed like the most sense, but didn't work. Can anyone help?
Thanks!!
GL
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"item"] || [elementName isEqualToString:#"channel"]) {
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"channel"]) {
// save values to an item, then store that item into the array...
[item setObject:currentTitle forKey:#"title"];
[item setObject:currentLink forKey:#"link"];
[item setObject:currentSummary forKey:#"summary"];
[item setObject:currentDate forKey:#"date"];
[feedsArray addObject:[item copy]];
}
if ([elementName isEqualToString:#"item"]) {
[item setObject:currentTitle forKey:#"title"];
[item setObject:currentLink forKey:#"link"];
[item setObject:currentSummary forKey:#"summary"];
[item setObject:currentDate forKey:#"date"];
[stories addObject:[item copy]];
NSLog(#"adding story: %#", currentTitle);
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:#"title"]) {
[currentTitle appendString:string];
} else if ([currentElement isEqualToString:#"link"]) {
[currentLink appendString:string];
} else if ([currentElement isEqualToString:#"description"]) {
[currentSummary appendString:string];
} else if ([currentElement isEqualToString:#"pubDate"]) {
[currentDate appendString:string];
}
}
The feed name is always included in the name of title by " - " at the end. Now if you want to get the feed name you can do it like.
NSDictionary *feedDict = [feedArray objectAtIndex:indexPath.row];
UILabel *lbl = (UILabel *)[cell.contentView viewWithTag:1];
NSArray *tempArr = [[NSArray alloc] initWithArray:[[feedDict valueForKey:#"title"] componentsSeparatedByString:#" - "]];
[lbl setText:[tempArr objectAtIndex:0]];
So you will see the name of feed in the lable.
Hope this helps.
Thanks,
Madhup
The feeds title lays outside items and channels so you should also trigger for a title in didStartElement. You also might need to make some logic to differentiate between titles within items and channels and the global title.
Let's have a try to fix it...(also noticed some possible memory leaks)
Not tested
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict {
if (currentElement)
[currentElement release];
currentElement = [elementName copy];
if ([elementName isEqualToString:#"item"] ||
[elementName isEqualToString:#"channel"]) {
if (item)
[item release];
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
} else if (!item && [elementName isEqualToString:#"title"]) {
[currentElement release];
currentElement = [#"<GlobalTitle>" copy];
}
}
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"channel"]) {
// save values to an item, then store that item into the array...
[item setObject:currentTitle forKey:#"title"];
[item setObject:currentLink forKey:#"link"];
[item setObject:currentSummary forKey:#"summary"];
[item setObject:currentDate forKey:#"date"];
[feedsArray addObject:item]; // item will be retained by array
[item release];
[currentTitle release]; // these are also retained by the dictionary
[currentLink release];
[currentSummary release];
[currentDate release];
item = nil;
currentTitle = nil;
currentLink = nil;
currentSummary = nil;
currentDate = nil;
}
if ([elementName isEqualToString:#"item"]) {
[item setObject:currentTitle forKey:#"title"];
[item setObject:currentLink forKey:#"link"];
[item setObject:currentSummary forKey:#"summary"];
[item setObject:currentDate forKey:#"date"];
[stories addObject:item]; // item will be retained by array
[item release];
[currentTitle release]; // these are also retained by the dictionary
[currentLink release];
[currentSummary release];
[currentDate release];
item = nil;
currentTitle = nil;
currentLink = nil;
currentSummary = nil;
currentDate = nil;
NSLog(#"adding story: %#", currentTitle);
}
}
- (void)parser:(NSXMLParser *)parser
foundCharacters:(NSString *)string {
if ([currentElement isEqualToString:#"title"]) {
[currentTitle appendString:string];
} else if ([currentElement isEqualToString:#"link"]) {
[currentLink appendString:string];
} else if ([currentElement isEqualToString:#"description"]) {
[currentSummary appendString:string];
} else if ([currentElement isEqualToString:#"pubDate"]) {
[currentDate appendString:string];
} else if ([currentElement isEqualToString:#"<GlobalTitle>"]) {
self.feedTitle = string; // The feeds title is saved here
}
}
I've released an open source RSS/Atom Parser for iPhone and it makes reading and parsing web feeds extremely easy.
You can set it to read just the feed info (title, summary, etc) if you want. Checkout the documentation and play around with the demo app. Hope this helps!