Working with XML in Swift (iOS/macOS): Parsing, Creation, and Processing

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Working with XML in Swift (iOS/macOS)



XML (Extensible Markup Language) remains a popular format for data exchange, configuration files, and storing structured information. In the Apple ecosystem (iOS, macOS, watchOS, tvOS), the built-in Foundation framework provides two main approaches to working with XML: streaming parsing (SAX-like) using XMLParser and tree-based DOM approach via XMLDocument (available on macOS). In this article, we will thoroughly examine both methods, provide practical examples, and cover typical use cases.



1. Streaming Parsing with XMLParser



XMLParser is an event-driven parser included in Foundation. It does not load the entire XML into memory but sequentially parses the document, calling delegate methods when it encounters elements, attributes, text, etc. This is an ideal solution for large files or streaming data.



Basic example of parsing an RSS feed



import Foundation

// 1. Create a delegate classclass RSSParserDelegate: NSObject, XMLParserDelegate { var currentElement = "" var currentTitle = "" var currentLink = "" var items: [(title: String, link: String)] = [] // Called when a start tag is encountered func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) { currentElement = elementName if elementName == "item" { currentTitle = "" currentLink = "" } } // Called when text content is found func parser(_ parser: XMLParser, foundCharacters string: String) { switch currentElement { case "title": currentTitle += string case "link": currentLink += string default: break } } // Called when an end tag is encountered func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { if elementName == "item" { items.append((title: currentTitle.trimmingCharacters(in: .whitespacesAndNewlines), link: currentLink.trimmingCharacters(in: .whitespacesAndNewlines))) } }}

// 2. Usagelet xmlString = """<rss> <channel> <item> <title>Swift 5.9 Features</title> <link>https://example.com/swift-5-9</link> </item> </channel></rss>"""

guard let data = xmlString.data(using: .utf8) else { fatalError() }let parser = XMLParser(data: data)let delegate = RSSParserDelegate()parser.delegate = delegate

if parser.parse() { for item in delegate.items { print("Title: \\(item.title), Link: \\(item.link)") }} else { print("Parse error: \\(parser.parserError?.localizedDescription ?? "unknown")")}


2. Tree Model: XMLDocument (macOS only)



On macOS (and in applications using Swift Package Manager with the Foundation framework in macOS mode), the XMLDocument class, inheriting from XMLNode, is available. It allows loading the entire XML into memory and manipulating it as a tree. This is convenient for small documents when random access to nodes is needed.



Creating and modifying an XML document



import Foundation

// Create the root elementlet rootElement = XMLElement(name: "catalog")let document = XMLDocument(rootElement: rootElement)

// Add a child element with an attributelet book = XMLElement(name: "book")book.addAttribute(XMLNode.attribute(withName: "id", stringValue: "101") as! XMLNode)let title = XMLElement(name: "title", stringValue: "Swift Programming")let author = XMLElement(name: "author", stringValu

Recommendations