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
Level 1
And a little deeper gives 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 }