Working with XML in Swift (iOS/macOS): complete guide
XML (eXtensible Markup Language) remains a popular format for data exchange, configuration files, and web services. In the Apple ecosystem, both built-in Foundation tools (the XMLParser class) and third-party libraries, such as SwiftXML, are available for working with XML in Swift. In this article, we will cover both approaches in detail with code examples for iOS and macOS.
1. Built-in XMLParser from Foundation
XMLParser is a SAX parser (sequential, event-driven). It does not load the entire document into memory but parses it as it reads, calling delegate methods. This is ideal for large XML files.
1.1. Basic setup and delegate
Create a class that implements the XMLParserDelegate protocol. Required methods:
parser(_:didStartElement:namespaceURI:qualifiedName:attributes:)— called when a tag opens.parser(_:foundCharacters:)— receives the text content of an element.parser(_:didEndElement:namespaceURI:qualifiedName:)— called when a tag closes.
import Foundation
class XMLHandler: NSObject, XMLParserDelegate { var currentElement = "" var currentText = ""
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) { currentElement = elementName currentText = "" if elementName == "book" { print("Start of book: \\(attributeDict["id"] ?? "")") } }
func parser(_ parser: XMLParser, foundCharacters string: String) { currentText += string }
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { if elementName == "title" { print("Title: \\(currentText.trimmingCharacters(in: .whitespacesAndNewlines))") } }}
// Usageif let url = Bundle.main.url(forResource: "books", withExtension: "xml"), let parser = XMLParser(contentsOf: url) { let handler = XMLHandler() parser.delegate = handler parser.parse()}1.2. Error handling and namespaces
Implement the parser(_:parseErrorOccurred:) method for logging errors. Use the namespaceURI and qualifiedName parameters for working with namespaces.
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) { print("Parsing error: \\(parseError.localizedDescription)")}2. Creating XML documents manually
To generate XML in Swift, you can use strings or the XMLDocument library from Foundation (available only on macOS). On iOS, you will need to create XML manually.
2.1. Generating XML via strings (iOS/macOS)
func createXMLString() -> String { var xml = "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>" xml += "<library>" xml += " <book id=\\"1\\">" xml += " <title>Swift Programming</title>" xml += " <author>Apple Inc.</author>" xml += " </book>" xml += "</library>" return xml}
let xmlString = createXMLString()print(xmlString)2.2. Using XMLDocument (macOS only)
import Foundation
let root = XMLElement(name: "library")let book = XMLElement(name: "book")book.addAttribute(XMLNode.attribute(withName: "id", stringValue: "1") as! XMLNode)
let title = XMLElement(name: "title", stringValue: "Swi