Автоматизация задач на Swift: от скуки к магии одной команды

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

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

Начать курс

Почему Swift — это не только про приложения

Когда слышишь «Swift», первая ассоциация — iOS-разработка, Xcode, сториборды и бесконечные констрейнты. Но есть и другая сторона этого языка, о которой знают далеко не все. Swift — это мощный инструмент для автоматизации задач на macOS. И речь не про компиляцию приложений, а про обычные, бытовые вещи: переименовать сотню файлов, распарсить CSV-отчёт, отправить уведомление в 18:00 или собрать логи с сервера.

Почему Swift, а не Python или Bash? Потому что Swift:

  • работает нативно с macOS (доступ к Foundation, Dispatch, UserNotifications);
  • не требует виртуального окружения и зависимостей (если не лезть в SPM);
  • даёт понятные ошибки компиляции — вы не потратите час на поиск лишнего пробела, как в Bash;
  • может быть запущен как скрипт одной строкой: swift myScript.swift.

В этой статье я покажу вам несколько реальных сценариев автоматизации на Swift. Вы сможете скопировать код, запустить его у себя и, главное, понять, как писать свои собственные утилиты. Поехали!

Как устроен Swift-скрипт: минимум теории

Чтобы написать автоматизацию на Swift, вам не нужен Xcode. Достаточно терминала и любого текстового редактора. Создайте файл script.swift и запустите его командой:

swift script.swift

Swift сам скомпилирует и выполнит код. Если скрипт большой и вы хотите ускорить повторные запуски, можно предварительно скомпилировать: swiftc -O script.swift -o script и запускать уже бинарник.

Всё, что мы будем писать дальше, работает из коробки — никаких сторонних библиотек. Только Foundation, который подключается автоматически.

Сценарий №1: Пакетное переименование файлов

Представьте: у вас папка с фотографиями IMG_001.jpg, IMG_002.jpg … IMG_100.jpg. Вы хотите переименовать их в Vacation_1.jpg, Vacation_2.jpg и так далее. Руками — 100 операций. Скриптом — 0.5 секунды.

import Foundation

let fileManager = FileManager.default
let currentPath = fileManager.currentDirectoryPath

guard let files = try? fileManager.contentsOfDirectory(atPath: currentPath) else {
    print("Не удалось прочитать папку")
    exit(1)
}

let imageFiles = files.filter { $0.hasSuffix(".jpg") || $0.hasSuffix(".png") }

for (index, file) in imageFiles.enumerated() {
    let newName = "Vacation_\(index + 1)." + (file.hasSuffix(".jpg") ? "jpg" : "png")
    let oldURL = URL(fileURLWithPath: currentPath).appendingPathComponent(file)
    let newURL = URL(fileURLWithPath: currentPath).appendingPathComponent(newName)
    
    do {
        try fileManager.moveItem(at: oldURL, to: newURL)
        print("✅ \(file) → \(newName)")
    } catch {
        print("❌ Ошибка с файлом \(file): \(error.localizedDescription)")
    }
}

Как это работает:

  • FileManager.default — доступ к файловой системе;
  • contentsOfDirectory — получаем список файлов в текущей папке;
  • фильтруем только изображения;
  • переименовываем через moveItem (да, в Swift переименование — это перемещение).

Вы можете легко адаптировать скрипт: менять префикс, расширения, добавлять дату в имя. Это уже полезный Swift скрипт, который экономит время каждый день.

Дополнительная фишка: суффикс с датой

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let dateString = dateFormatter.string(from: Date())

for (index, file) in imageFiles.enumerated() {
    let newName = "\(dateString)_\(index + 1).jpg"
    // ... дальше как в примере выше
}

Сценарий №2: Парсинг CSV и генерация отчёта

Офисные сотрудники и разработчики часто сталкиваются с CSV-файлами. Экспорт из Excel, Google Sheets, CRM. Вручную обрабатывать 500 строк — тоска. Напишем скрипт, который читает CSV, фильтрует строки по условию и выводит результат.

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

ID,Name,Department,Salary
1,Иван Иванов,IT,150000
2,Мария Петрова,HR,120000
3,Алексей Смирнов,IT,170000
4,Ольга Кузнецова,Marketing,130000

Мы хотим найти всех сотрудников из IT с зарплатой выше 140 000.

import Foundation

let filePath = "employees.csv"
guard let content = try? String(contentsOfFile: filePath, encoding: .utf8) else {
    print("❌ Не удалось прочитать файл")
    exit(1)
}

let rows = content.components(separatedBy: "\n").filter { !$0.isEmpty }
let header = rows.first!
let dataRows = Array(rows.dropFirst())

print("Фильтр: отдел IT, зарплата > 140000")
print("-------------------------------")
print(header)

for row in dataRows {
    let columns = row.components(separatedBy: ",")
    guard columns.count >= 4 else { continue }
    
    let department = columns[2].trimmingCharacters(in: .whitespaces)
    let salaryString = columns[3].trimmingCharacters(in: .whitespaces)
    
    if department == "IT", let salary = Int(salaryString), salary > 140000 {
        print(row)
    }
}

Этот код — основа для автоматизации обработки данных на Swift. Вы можете расширить его: записывать результат в новый CSV, отправлять по email (через Process и mail), или даже строить простую HTML-таблицу.

Сценарий №3: Уведомления по расписанию

Хотите, чтобы скрипт напоминал вам выпить воду, сделать перерыв или запустить бекап? Swift имеет прямой доступ к UserNotifications на macOS. Можно отправить уведомление прямо в Центр уведомлений.

import Foundation
import UserNotifications

// Запрашиваем разрешение (нужно только один раз)
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) { granted, error in
    if granted {
        print("✅ Разрешение получено")
    } else {
        print("❌ Разрешение отклонено")
    }
}

// Создаём уведомление
let content = UNMutableNotificationContent()
content.title = "Напоминание"
content.body = "Пора сделать перерыв! Встаньте и пройдитесь."
content.sound = UNNotificationSound.default

// Триггер через 5 секунд (для теста)
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content                

Блоги

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