CLI фреймворк для Swift (iOS/macOS): ArgumentParser
В мире разработки под экосистему Apple часто возникает необходимость создавать не только графические приложения, но и мощные консольные утилиты. Будь то автоматизация сборки, обработка данных или создание вспомогательных инструментов для iOS/macOS — без качественного CLI (Command Line Interface) не обойтись. Для этих целей Apple предлагает официальный фреймворк ArgumentParser, входящий в состав Swift Package Manager. Это современный, типобезопасный и декларативный инструмент, который позволяет с минимальными усилиями создавать консольные приложения на Swift.
В отличие от простого парсинга аргументов через CommandLine.arguments, ArgumentParser предоставляет структурированный подход: вы описываете команды, флаги и опции в виде свойств ваших структур, а фреймворк автоматически генерирует справку, обрабатывает ошибки и валидирует ввод. Давайте разберёмся, как использовать этот фреймворк для macOS и iOS (через Swift Package Manager).
Установка и подключение
ArgumentParser не требует отдельной установки — он доступен в составе стандартной библиотеки Swift (начиная с Swift 5.5). Для использования в вашем проекте добавьте зависимость в Package.swift:
// swift-tools-version:5.7
import PackageDescription
let package = Package(
name: "MyCLI",
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.2.0")
],
targets: [
.executableTarget(
name: "MyCLI",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser")
]
)
]
)
Для iOS-проектов фреймворк можно добавить через Swift Package Manager в Xcode, указав тот же репозиторий. Однако стоит помнить, что CLI-приложения обычно создаются для macOS, но библиотека может использоваться и в iOS-приложениях для внутреннего парсинга строк.
Основные концепции
ArgumentParser строится вокруг трёх ключевых сущностей:
- Команды (
ParsableCommand) — основной элемент, представляющий собой одну команду CLI. Каждая команда — это структура, реализующая протоколParsableCommand. - Аргументы (
@Argument) — позиционные параметры, обязательные для ввода. - Опции (
@Option) — именованные параметры с длинным (--name) и коротким (-n) флагами. - Флаги (
@Flag) — булевы переключатели (--verbose, --quiet).
Пример: создание простого CLI-калькулятора
Создадим консольное приложение для macOS, которое выполняет базовые арифметические операции:
import ArgumentParser
struct Calculator: ParsableCommand {
static let configuration = CommandConfiguration(
commandName: "calc",
abstract: "Простой калькулятор для командной строки",
discussion: "Поддерживает сложение, вычитание, умножение и деление."
)
@Argument(help: "Первое число")
var firstNumber: Double
@Argument(help: "Второе число")
var secondNumber: Double
@Option(name: [.short, .long], help: "Операция: add, sub, mul, div")
var operation: String = "add"
@Flag(name: [.short, .long], help: "Подробный вывод")
var verbose: Bool = false
mutating func run() throws {
let result: Double
switch operation {
case "add":
result = firstNumber + secondNumber
case "sub":
result = firstNumber - secondNumber
case "mul":
result = firstNumber * secondNumber
case "div":
guard secondNumber != 0 else {
throw ValidationError("Деление на ноль!")
}
result = firstNumber / secondNumber
default:
throw ValidationError("Неизвестная операция: \(operation)")
}
if verbose {
print("Операция: \(operation)")
print("Числа: \(firstNumber) и \(secondNumber)")
}
print("Результат: \(result)")
}
}
Calculator.main()
Теперь вы можете запустить скомпилированный бинарник из терминала:
$ swift run calc 10 5 --operation mul --verbose
Операция: mul
Числа: 10.0 и 5.0
Результат: 50.0
Продвинутые возможности: вложенные команды
Для сложных инструментов можно создавать иерархию команд. Например, утилита для работы с файлами может содержать подкоманды copy, move, delete. Реализуется это через свойство subcommands в конфигурации:
struct FileTool: ParsableCommand {
static let configuration = CommandConfiguration(
commandName: "filetool",
subcommands: [Copy.