Parse XML - Version 1

Version 2

It might be worth looking at Swift Codable to do this. Description given in Whats new in Swift 4? Section 3 of Udemy Course Practical iOS 11 by Stephen DeStefano

See also Swift Encoders

Using XMLParserDelegate

Using the TWIT.tv podcast feed as an example: http://feeds.twit.tv/mbw.xml

Level 1
XML - Level 1

And a little deeper gives level 2.

XML - Level 2

Start by including XMLParserDelegate in your class. Declare variable xmlParser, currentParsedElement and depth.

xmlParser is the parser method provided by Apple
currentParsedElement is used to hold the current elemeent being parsed
depth is the XML level of the item(s) to be retrieved.

class PodcastsViewController: NSViewController, XMLParserDelegate
{
...
	var xmlParser: XMLParser!
	var currentParsedElement = ""    
	var depth = 0
...

Data is retrieved from the podcast site/website

if data != nil
{
	self.xmlParser = XMLParser(data: data!)
	self.xmlParser.delegate = self
	self.xmlParser.parse()

The parser works in three stages, beginning, the characters and the end with three separate functions.

func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: 
    String?, qualifiedName qName: String?, 
    attributes attributeDict: [String : String] = [:])
    {
        depth = depth + 1
        currentParsedElement = ""

        if elementName == "title" && depth == 3
        {
            currentParsedElement = elementName
            entryTitle = ""
        }

        if elementName == "itunes:image" && depth == 3
        {
            currentParsedElement = elementName
            entryImageURL = attributeDict["href"]!
        }
    }

The elementName is the XML descriptor, e.g. level 1: title, link, generator, level 2: itunes:name, itunes:email. The level is specified using the depth variable. This gives the starting point for each item. The next function gather the entry, one character at a time.

func parser(_ parser: XMLParser, foundCharacters string: String)
{
	switch currentParsedElement
	{
		case "title":
			entryTitle = entryTitle + string
		default:
			break
	}
}

The last function detects the end of the item and returns the data and restores the depth (level).

func parser(_ parser: XMLParser, didEndElement elementName: String,
    namespaceURI: String?, qualifiedName qName: String?)
{
	if elementName == "title" && depth == 3
	{
//            print("title: \(entryTitle)")
	}
	if elementName == "itunes:image" && depth == 3
	{
//            print("imageURL: \(entryImageURL)")
	}
	currentParsedElement = ""
	depth = depth - 1
}

Reference:

Index


Comments, Corrections, Suggestions: David Bourne (david@boomer.org)
My iOS and tvOS Apps and iBooks