How to reload the UIView after NSXMLParser in Iphone? - iphone

I am using NSXMLParser to parse some xml data. I am using some delegate method like,
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
This NSXMLParser is in MYAppDelegate.m, Now I want to reload the UI after completing the parsing on Home.m, also I start activity indicator when I request to web service and stop it in didEndElement. But I noticed sometimes found character dosen't get called and My UI freezes. I want to update my UI after parsing is completed. How I can do this?
Thanks in advance.

You can try to reload your view in:
Sent by the parser object to the delegate when it has successfully completed parsing:
- (void)parserDidEndDocument:(NSXMLParser *)parser
Sent by a parser object to its delegate when it encounters a fatal error. When this method is invoked, parsing is stopped:
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError

You can create an NSOperation subclass and try to parse XML in that class to avoid UI freezing more info how to achieve this , take a look here NSOperaion
to redraw UIView call [self.view setNeedsDisplay];

When your app's
- (void)parserDidEndDocument:(NSXMLParser *)parser
is called then you want to do
[self reloadView];
or whatever your reload method is.

Related

Difficulty parsing RSS feed

I'm trying to parse an RSS feed (http://www.themostunrealbeats.com/?feed=rss2) using NSXMLParser. I am having difficulty finding the picture in the article. Here is where the picture is in the RSS feed.
<media:content url="http://themostunrealbeats.files.wordpress.com/2012/03/madeon.png?w=400" medium="image">
<media:title type="html">madeon</media:title>
</media:content>
Specifically, I want http://themostunrealbeats.files.wordpress.com/2012/03/madeon.png. Yet in the delegate method for NSXMLParser, I don't find anything.
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([element isEqualToString:#"media:content"]) {
NSLog(#"%#", string);
[content appendString:string];
}
}
string has no value. How can I parse this?
// NSXMLParser has a following method
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
// In this method parameter 'attributeDict' will return you all the sub attributes of main attribute.
// In your case its 'url' of Picture.
// I hope this will help you. Check this out.

NSXMLParser issue : don't get all data?

I'm developing an application that needs to get data from an XML file. Some of the nodes have a lot of characters and I've a problem using this function :
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
For example for the description node of an item I will get only the 20-30 last characters whereas I would get 200 or 300.
I checked this out with a NSLog and it appears the problem comes from here. Do you know what's wrong ?
Thanks for any advice.
SAX parsers do not guarantee to get all characters at once. You may get multiple calls with chunks of characters from any given block; your code should concatenate them into a single string.
The parser object may send the delegate several parser:foundCharacters: messages to report the characters of an element. Because string may be only part of the total character content for the current element, you should append it to the current accumulation of characters until the element changes.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
if ([qualifiedName isEqualToString:#"myTag"]) {
buf = [NSMutableString string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([qualifiedName isEqualToString:#"myTag"]) {
buf = [buf stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(#"Got %#", buf);
}
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[buf appendString:string];
}

Leak in the NSXML Parser

It seems like there is memory leak in this piece of code.I am using this to parse XML data.
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
currentElement = [[elementName copy]autorelease];
if ([elementName isEqualToString:#"value1"]) {
self.currentString =[NSMutableString string];
}
else if ([elementName isEqualToString:#"value2"]) {
self.currentStringName =[NSMutableString string];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([currentElement isEqualToString:#"value1"]) {
[currentString appendString:string];
}
else if ([currentElement isEqualToString:#"value2"]) {
[currentStringName appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"value1"]) {
}
else if ([elementName isEqualToString:#"value2"])
{
}
You may want to make a little research of the style "NSXMLParser leak". Like a few other pieces of the SDK, NSXMLParser is a broken dam. I dont see in your code (after, I must say, a very quick glance) any leaks... I mean compared to what you'll find in NSXMLParser. And unfortunately, you can't do anything about them.
So, basically, if Instruments, for example, is reporting leaks with your code, don't be ashame: NSXMLParser is responsible.
If you have the chance, don't hesitate to keep control of the objects you create (and avoid autorelease), it's way easier to manage in my opinion (but...some could disagree!).
Try using other XML Parsers like touchXML or KissXML. NSXML Parser does have leaks inside the framework.

xml parsing iphone issue

I'm using the NSXMLParser however i dont quite understand how to display items from a xml correctly. E.g. i have this in the xml parser:
- (void) parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"level4"]) {
//add a book object to the array at the index determined by bookCount
self.bookCount++;
[books addObject:[[book alloc]init]];
//[books insertObject:[[book alloc]init] atIndex:self.bookCount];
}
if ([elementName isEqualToString:#"module"]) {
isFirstName = YES;
}
if ([elementName isEqualToString:#"moduleTitle"]) {
isLastName = YES;
}
if ([elementName isEqualToString:#"semester"]) {
isTitle = YES;
}
if ([elementName isEqualToString:#"assessmentName"]) {
isGenre = YES;
}
}
This is my xml
<myCourse>
<courseName>BEng Mobile and Web Computing</courseName>
<courseStructure>
<level4>
<module>
<moduleCode>ECSC401</moduleCode>
<moduleTitle>Programming Methodology</moduleTitle>
<credits>15</credits>
<semester>1</semester>
<assessmentDetails>
<assessment>
<assessmentName>Test1</assessmentName>
<assessmentType>Coursework</assessmentType>
<assessmentWeighting>30</assessmentWeighting>
<assessmentDueDate/>
</assessment>
<assessment>
<assessmentName>Coursework</assessmentName>
<assessmentType>Coursework</assessmentType>
<assessmentWeighting>40</assessmentWeighting>
<assessmentDueDate/>
</assessment>
<assessment>
<assessmentName>Test2</assessmentName>
<assessmentType>Coursework</assessmentType>
<assessmentWeighting>30</assessmentWeighting>
<assessmentDueDate/>
</assessment>
</assessmentDetails>
</module>
</level4>
</courseStructure>
</myCourse>
(it continues level 1,level2,level3 using the same format). I simply want to display all the modules under the 'level4' hierarchy - how can i do this?/what am i doing wrong? the items are displaying just not the right ones ..
First of all you have to create one NSMutableDictionary. When you get the tag in didStartElement Method initiate this Dictionary.And also set one flag.
And in Found character method check that flag, if It is then store that tagValues and in didEndElement store all the values in this Dictionary when you find .
You can find all levels values using this.
Hope this will help you.
Use both methods:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
and
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
For parsing.

Is there a way to get NSXMLParser to ignore the "&amp" and similar symbols while parsing XML?

I'm currently parsing an xml file that has a string like this between two elements:
Hello & bye
When the foundCharacters delegate gets called it parses the information like this....
it parses:
Hello
&
bye
It makes 3 calls to parse that element and I end up with 3 strings as opposed to 1 string. Is there some way to detect this with out having to append a string together and keep a counter of how many times the delegate was called?
Any help is very appreciated...
Short answer : No. It's only chance that it's returning three strings, it might return 11 strings all one character long if it wanted to. It's up to you to join the strings together.
Long answer : You need to append a string. There's nothing you can do about it. however, I don't understand why you need to keep a count of the number of times the delegate has been called - I think that this code should do what you want :
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
// Make a new string to hold the data
[currentString release];
currentString = [NSMutableString alloc] init];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
// Add the string to our current string
[currentString appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
// In here, current string should be it's entire contents,
NSLog(#"%#", currentString);
}
You will need a member in your class to hold the data - a mutable string is easiest one:
#interface MyClass : NSObject {
NSMutableString *currentString;
}
#end
(It doesn't need to be a property but you do need to remember to release it in your dealloc method)