1

I am parsing using an XML file. I want to show a Progress Bar till the parsing procedure completes. How can I calculate the progress of the ProgressView ?? Pls Help..

Zaraki
  • 3,720
  • 33
  • 39

3 Answers3

6

First, count the number of lines.

NSError *error = nil;
NSString *xmlFileString = [NSString stringWithContentsOfURL:url
                           encoding:NSUTF8StringEncoding error:&error];
_totalLines = [xmlFileString componentsSeparatedByString:@"\n"].count;

Then, catch the progress in delegate method block. For example:

- (void)parser:(NSXMLParser *)parser 
  didStartElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI 
  qualifiedName:(NSString *)qName 
  attributes:(NSDictionary *)attributeDict
{
    [self.elementStack addObject:elementName];

    NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
    [mainQueue addOperationWithBlock:^{
        _progressView.progress = (CGFloat)[parser lineNumber] / (CGFloat)_totalLines;
    }];
}

Sample Project is Here:

https://github.com/weed/p120727_XMLParseProgress

ss

Community
  • 1
  • 1
Feel Physics
  • 2,783
  • 4
  • 25
  • 38
5

If you are parsing with NSXMLParser and know the length of the file being parsed, you can approximate progress by calling lineNumber on your parser object to tell you how far through the file the parser is.

progressView.progress = (CGFloat)[parser lineNumber] / (CGFloat)totalLines;
jnic
  • 8,695
  • 3
  • 33
  • 47
  • xml file is not constant.. it changes everyday so the length is not static..is there any way to find the size or length of the file being parsed??? – Zaraki Mar 25 '11 at 12:17
  • 1
    If your data is a string, you can just count the newlines: `[[xmlFileString componentsSeparatedByString:@"\n"] count];` – jnic Mar 25 '11 at 12:26
  • @jnic: please elaborate ... how to calculate progress using this – Zaraki Mar 29 '11 at 09:16
  • `progress` takes a value between 0 and 1, which, happily, is what you get by dividing the current line number that your parser is on by the total number of lines to parse. You'll need to regularly update this value to animate your bar, either by polling or by using a callback from `NSXMLParserDelegate`. – jnic Mar 29 '11 at 09:26
  • @jnic: I am still unable to do it.. please can u help, i am using this link (feed://timesofindia.feedsportal.com/c/33039/f/533917/index.rss) for RSS parsing, using an NSXML parser with didStartElement, didEndElement and FoundCharacters. Can u help me with an example, how to get the progress value so that i can understand what i have to do.. ?? – Zaraki Apr 07 '11 at 12:15
0

I'm processing large files where it was taking several seconds to count how many lines there are in the file.

I came up with a more complex but faster solution:

  • map the contents of the file into virtual memory, using NSData. This is the fastest way to read a large file on OS X and iOS. It will be loaded into RAM if it's a small/medium sized file, but large files will only partially be loaded into RAM.
  • using grand central dispatch, fire off a background task to process the data in 10KB chunks, counting how many newlines are found.
  • fire off another grand central dispatch task to parse the same NSData object.
  • whenever a new tag is started, every half a second, check if the line counting has finished, and if so it updates the progress bar.

Mapping a file into virtual memory and then seraching for newline bytes is around 10x faster than any other method I could find, including some low level C choices. It takes a split second to count a file with 3 million lines on my SSD equiped mac.

Doing it on a background thread, in parallel with NSXMLParser on the same NSData object, ensures the file will not be read from the disk twice (unless the file is too big to fit in RAM).

Source code for this is here: https://github.com/abhibeckert/Speed-Limit/blob/master/Speed%20Limit/SLOSMImporter.m

Note: the code I posted will work on iOS 7 and OS X 10.9. It has only been tested on OS X 10.9. It could be modified fairly easily to work on older versions of the SDK, just build it and the compile errors should be easy to fix.

Abhi Beckert
  • 32,787
  • 12
  • 83
  • 110