Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use NSXMLParser to only parse the first ten posts, then parse next lot separately

I am using NSXmlParser to parse through an rss feed. All is working well so far.

I'm anticipating the rss feed will eventually contains dozens/hundreds of posts. My current solution is reading the entire rss feed and displaying the results. However I want to only read the first ten posts (to prevent it parsing potentially hundreds of items). Then at a later time (say when the user reaches the end of the table) to parse the next ten posts.

So my question is how would I parse the first ten posts, then parse the next ten posts, then the next ten posts and so on...

Here is what I am using to get ALL posts:

- (void)parseXMLFileAtURL:(NSString *)URL
{   
    myArray = [[NSMutableArray alloc] init];

    //convert the path to a proper NSURL or it won't work
    NSURL *xmlURL = [NSURL URLWithString:URL];

    rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
    [rssParser setDelegate:self];
    [rssParser parse];

}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    //error
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{            

    currentElement = [elementName copy];

    if ([elementName isEqualToString:@"item"]) {
        //clear out our story item caches...
        item = [[NSMutableDictionary alloc] init];

    }

}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{     

    if ([elementName isEqualToString:@"item"]) {
        // save values to an item, then store that item into the array...
    }

}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{

    // save the characters for the current item...

}

- (void)parserDidEndDocument:(NSXMLParser *)parser {

    [myTable reloadData];

}
like image 927
Andrew Davis Avatar asked Jul 03 '12 19:07

Andrew Davis


1 Answers

In a different style answer from the others, I want to contribute that if your parser is taking this long to parse where the difference between 10 and 100 is a significant human-measurable quantity, then you are doing something wrong. It is probably best to:

  1. Profile your parsing code to find the slowdown (or find a more performant XML library)
  2. Parse the entire lot on a background thread
  3. Only display the first 10 to the user,
  4. Display the rest from memory as they go.

It is a double win because parsing it all at once makes for simpler code and less bugs, and "loading" (showing) an rss "page" one at a time will be lightning fast and your users will love you (see Instagram for examples on faking speed)

like image 143
coneybeare Avatar answered Nov 16 '22 03:11

coneybeare