Работа с XML в Swift (iOS/macOS): Foundation и SwiftXML

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с XML в Swift (iOS/macOS): полное руководство

XML (eXtensible Markup Language) остаётся востребованным форматом для обмена данными, конфигурационных файлов и веб-сервисов. В экосистеме Apple для работы с XML в Swift доступны как встроенные средства Foundation (класс XMLParser), так и сторонние библиотеки, например SwiftXML. В этой статье мы подробно разберём оба подхода с примерами кода для iOS и macOS.

1. Встроенный XMLParser из Foundation

XMLParser — это SAX-парсер (последовательный, событийно-ориентированный). Он не загружает весь документ в память, а разбирает его по мере чтения, вызывая методы делегата. Это идеально для больших XML-файлов.

1.1. Базовая настройка и делегат

Создайте класс, реализующий протокол XMLParserDelegate. Обязательные методы:

  • parser(_:didStartElement:namespaceURI:qualifiedName:attributes:) — вызывается при открытии тега.
  • parser(_:foundCharacters:) — получает текстовое содержимое элемента.
  • parser(_:didEndElement:namespaceURI:qualifiedName:) — вызывается при закрытии тега.
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("Начало книги: \(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("Название: \(currentText.trimmingCharacters(in: .whitespacesAndNewlines))")
        }
    }
}

// Использование
if let url = Bundle.main.url(forResource: "books", withExtension: "xml"),
   let parser = XMLParser(contentsOf: url) {
    let handler = XMLHandler()
    parser.delegate = handler
    parser.parse()
}

1.2. Обработка ошибок и пространства имён

Реализуйте метод parser(_:parseErrorOccurred:) для логирования ошибок. Для работы с пространствами имён используйте параметры namespaceURI и qualifiedName.

func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
    print("Ошибка парсинга: \(parseError.localizedDescription)")
}

2. Создание XML-документов вручную

Для генерации XML в Swift можно использовать строки или библиотеку XMLDocument из Foundation (доступна только на macOS). На iOS придётся создавать XML вручную.

2.1. Генерация XML через строки (iOS/macOS)

func createXMLString() -> String {
    var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    xml += "<library>\n"
    xml += "  <book id=\"1\">\n"
    xml += "    <title>Swift Programming</title>\n"
    xml += "    <author>Apple Inc.</author>\n"
    xml += "  </book>\n"
    xml += "</library>\n"
    return xml
}

let xmlString = createXMLString()
print(xmlString)

2.2. Использование XMLDocument (macOS только)

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: "Swift Programming")
let author = XMLElement(name: "author", stringValue: "Apple Inc.")

book.addChild(title)
book.addChild(author)
root.addChild(book)

let document = XMLDocument(rootElement: root)
document.version = "1.0"
document.characterEncoding = "UTF-8"

let data = document.xmlData(options: .nodePrettyPrint)
if let xmlString = String(data: data, encoding: .utf8) {
    print(xmlString)
}

3. Библиотека SwiftXML

SwiftXML — современная библиотека с открытым исходным кодом, которая предоставляет DOM-подобный API (документ загружается в память целиком). Поддерживает XPath, пространства имён и преобразование в JSON.

3.1. Установка через Swift Package Manager

// Package.swift
dependencies: [
    .package(url: "https://github.com/Sw                    

Рекомендаций