Работа с CSV в Swift (iOS/macOS): библиотеки и примеры

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

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

Начать курс

Работа с CSV в Swift (iOS/macOS): от простого к сложному

CSV (Comma-Separated Values) — один из самых распространённых форматов для обмена табличными данными. Он используется для экспорта из Excel, Google Sheets, баз данных и простых логов. В экосистеме Swift (iOS, macOS, watchOS, tvOS) нет встроенного модуля для работы с CSV, но существует несколько проверенных библиотек, которые значительно упрощают этот процесс. В этой статье мы рассмотрим лучшие инструменты и напишем несколько примеров кода.

Почему не стоит писать парсер CSV вручную?

На первый взгляд CSV кажется простым: разделили строку по запятым — и готово. Однако на практике возникают сложности:

  • Поля могут содержать запятые внутри (например, "Smith, John").
  • Поля могут быть обёрнуты в кавычки, а внутри кавычек — экранированные кавычки ("").
  • Разные системы используют разные разделители (запятая, точка с запятой, табуляция).
  • Проблемы с кодировками (UTF-8, UTF-16, Windows-1251).

Поэтому для production-кода настоятельно рекомендуется использовать готовую библиотеку.

Лучшие библиотеки для CSV в Swift

1. SwiftCSV (от Naoto Kaneko)

Одна из самых популярных и лёгких библиотек. Поддерживает чтение и запись, автоматически обрабатывает кавычки и экранирование. Работает через Swift Package Manager (SPM) и CocoaPods.

// Подключение через SPM: .package(url: "https://github.com/naoty/SwiftCSV.git", from: "0.9.0")

2. CodableCSV (от Dehesa)

Современная библиотека, которая интегрируется с протоколом Codable. Позволяет парсить CSV напрямую в структуры Swift. Идеально для проектов, где данные имеют строгую типизацию.

// Подключение: .package(url: "https://github.com/dehesa/CodableCSV.git", from: "0.6.0")

3. CSwift

Простая и быстрая библиотека с минимальным API. Хорошо подходит для небольших проектов или быстрого прототипирования.

Пример 1: Чтение CSV с помощью SwiftCSV

Допустим, у нас есть файл users.csv:

id,name,email
1,Иван Иванов,ivan@example.com
2,Мария Петрова,maria@example.com
3,Джон Доу,"john.doe@example.com"

Код для чтения:

import SwiftCSV

guard let csvURL = Bundle.main.url(forResource: "users", withExtension: "csv") else {
    print("Файл не найден")
    return
}

do {
    let csv = try CSV(url: csvURL)
    // Доступ к строкам как к массиву словарей
    for row in csv.rows {
        if let id = row["id"], let name = row["name"], let email = row["email"] {
            print("ID: \(id), Имя: \(name), Email: \(email)")
        }
    }
    // Или доступ по столбцам
    print("Все имена: \(csv.columns["name"] ?? [])")
} catch {
    print("Ошибка парсинга: \(error)")
}

Пример 2: Запись CSV с помощью SwiftCSV

import SwiftCSV

let headers = ["Name", "Age", "City"]
let rows = [
    ["Анна", "28", "Москва"],
    ["Борис", "35", "Санкт-Петербург"],
    ["Виктор", "22", "Новосибирск"]
]

do {
    let csv = try CSV(string: "", headers: headers, rows: rows)
    let csvString = csv.output // Получаем строку CSV
    print(csvString)
    // Сохраняем в файл
    let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let fileURL = documentsPath.appendingPathComponent("output.csv")
    try csvString.write(to: fileURL, atomically: true, encoding: .utf8)
    print("Файл сохранён: \(fileURL)")
} catch {
    print("Ошибка записи: \(error)")
}

Пример 3: CodableCSV — парсинг в структуры

Этот пример показывает, как легко интегрировать CSV с моделями данных:

import CodableCSV

struct User: Decodable {
    let id: Int
    let name: String
    let email: String
}

guard let csvURL = Bundle.main.url(forResource: "users", withExtension: "csv") else { return }

do {
    let data = try Data(contentsOf: csvURL)
    let decoder = CSVDecoder { $0.headerStrategy = .firstLine }
    let users = try decoder.decode([User].self, from: data)                    

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