Parse an XML file in chunks without waiting for complete download in Swift Parse an XML file in chunks without waiting for complete download in Swift xml xml

Parse an XML file in chunks without waiting for complete download in Swift


There are basically two type of parser: SAX and DOM. As per your requirement, where you are updating UITableView as soon as XML element received, It is perfectly clear that you will have to use SAX parser only. (DOM parser parsed the entire document and builds up an in-memory representation that you can query for different elements).

There are two popular SAX parser for iOS as listed below:

1)NSXMLParser (This has been renamed to XMLParser) - included by default with the iPhone SDK.

2)libxml2 - is an Open Source library that is included by default with the iPhone SDK

Apple has made an excellent code sample called XMLPerformance that allows you to compare the time it takes to parse a ~900KB XML document containing the top 300 iTunes songs with both the NSXML and libxml2 APIs.

Ok, here’s a graph that shows the peak memory usage by parser (this was obtained through running the various methods through the Object Allocations tool)

a busy cat

Data clearly shows that libxml2’s SAX method (Which you already tried) is the best option as far as peak memory usage is concerned.

On the other hand, implementing XMLParser is quite easy. Below is my example snippet which i tried using it.

In your class declaration, implement the XMLParserDelegate protocol

class ViewController: UIViewController,XMLParserDelegate {override func viewDidLoad() {    super.viewDidLoad()

Use below method to initialize the parser:

func xmlParser(){    posts = []    parser = XMLParser(contentsOf:(NSURL(string:"http://images.apple.com/main/rss/hotnews/hotnews.rss"))! as URL)!    parser.delegate = self    parser.parse()}

Once you initialize the delegate, below delegate methods will get called as and when needed:

func parserDidStartDocument(_ parser: XMLParser) {    print("started")}func parserDidEndDocument(_ parser: XMLParser) {    print("ended")}func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {    print("didEndElement")}func parser(_ parser: XMLParser, foundCharacters string: String) {    print("foundCharacters")}

There are other delegate methods as well which you can call according to your requirements.


Maybe the client/server has a problem with some Session-Cookies? Try to delete them after each request:

// Loops through each of the cookies and deletes them.let cookieStore = HTTPCookieStorage.sharedfor cookie in cookieStore.cookies ?? [] {    cookieStore.deleteCookie(cookie)} 


The below solution may help you out. I have explored about your question and succeed some what as a result below. But I can't able to test the below solution lack of API's. Try with your available Endpoints. Hope it will help you.

func xmlStream() {        let task =            URLSession.shared.streamTask(withHostName: "chat.example.com", port: 5555)                                                                   task.readData(ofMinLength: 16384, maxLength: 65536, timeout: 30.0) { (data, eof, error) in            let parser = XMLParser(data: data!)            parser.delegate = self            if parser.parse() {                //print result            }        }        task.resume()    }//XML parser methods

Moreover this may guide you.