Как собирать и выпускать приложения для Mac и iOS, не открывая Xcode
Собираем Apple-приложения без Xcode: терминал как новая IDE
Знаете, что меня всегда раздражало? Xcode. Красивая, мощная, невероятно громоздкая штука. Открываешь её, ждёшь, пока она загрузится, а потом ещё пять минут вспоминаешь, где в этом интерфейсе что находится.
Недавно наткнулся на статью Скотта Уилси (Scott Willsey) — и она перевернула моё представление о сборке Apple-приложений. Оказывается, можно собрать, подписать и отправить в релиз хоть десять приложений, и ни разу не кликнуть на иконку Xcode.
Зачем вообще заморачиваться с CLI
CLI (CLI — интерфейс командной строки, где вы печатаете команды вместо кликов мышью; простыми словами: терминал) — это всегда было про GUI (GUI — графический интерфейс с кнопками и окошками, как привычный интерфейс Xcode). Открой Xcode, создай проект, тыкай по кнопкам. Но что если вам не нужна вся мощь редактора? Что если вы:
- Пишете скриптовый инструмент для себя
- Автоматизируете деплой через CI/CD (CI/CD — непрерывная интеграция и доставка; автоматическая сборка и тестирование кода при каждом изменении)
- Хотите встроить сборку в свой пайплайн
GUI — это хорошо для обучения и отладки. Но для продакшена терминал надёжнее: меньше кликов, меньше ошибок, легко повторить.
Автор статьи приводит простой тезис: Xcode.app (папка-приложение в macOS; то же самое что .exe в Windows, только в виде папки) должен быть установлен, но его не нужно открывать. Все инструменты сборки живут внутри приложения и прекрасно работают из командной строки.
Инструменты, которые нам понадобятся
Вот минимальный набор для полноценного релизного цикла:
xcodebuild — основной инструмент сборки. Создаёт архив приложения (.xcarchive) из командной строки.
notarytool — отправляет подписанное приложение в Apple для проверки на малварь. Без нотаризации macOS заблокирует ваше приложение.
stapler — прикрепляет результат нотаризации к приложению. Нужна для того, чтобы Gatekeeper (Gatekeeper — охранник macOS, который проверяет, можно ли запускать скачанные приложения) пропустил ваш .app.
xcode-select — переключает командную строку между разными версиями Xcode. Важно: убедитесь, что система использует именно Xcode.app, а не standalone Command Line Tools.
XcodeGen — генератор проектов. Создаёт файл project.yml, из которого на лету генерирует .xcodeproj. Больше не нужно коммитить в git здоровенные файлы проекта Xcode.
ЖИЗНЕННЫЙ ЦИКЛ APPLE-ПРИЛОЖЕНИЯ
───────────────────────────────
Исходный код ──▶ project.yml ──▶ .xcodeproj
│
▼
xcodebuild archive
│
▼
.xcarchive (архив)
│
┌──────┴──────┐
▼ ▼
Developer ID notarytool
подпись │
│ ▼
│ stapler
│ │
└─────┬─────┘
▼
Готовый .app
для распространения
Одноразовая настройка: где придётся потерпеть GUI
Честно предупрежу: есть вещи, которые делаются один раз через графический интерфейс. Без этого никак.
Подготовка Xcode. Устанавливаете приложение, принимаете лицензию и устанавливаете компоненты:
sudo xcodebuild -license accept sudo xcodebuild -runFirstLaunch
Проверьте, что командная строка указывает на Xcode.app:
xcode-select -p ## Должно быть: /applications/xcode.app/contents/developer
Если видите путь к CommandLineTools — поправьте:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
Apple Developer аккаунт. Платный аккаунт ($99 в год) обязателен для нотаризации. Без неё macOS Catalina и новее откажутся запускать ваше приложение.
Developer ID Certificate. Создаётся один раз в Xcode (Settings → Accounts → Manage Certificates). Это часть code signing (подпись кода — электронная «печать» приложения, подтверждающая, что его создали вы, а не мошенники). Автор статьи особенно подчёркивает: это сертификат и приватный ключ. Приватный ключ нельзя скачать повторно. Потеряете — придётся отзывать сертификат и создавать новый.
Профиль нотаризации. notarytool требует интерактивного ввода app-specific password:
xcrun notarytool store-credentials App-Name \ --apple-id "email@example.com" \ --team-id YOUR-TEAM-ID
Этот пароль генерируется на appleid.apple.com и живёт в вашем keychain (Keychain — защищённое хранилище паролей в macOS; цифровой сейф для ваших паролей и сертификатов). Меняете пароль Apple ID — пароль устаревает, нотаризация падает с загадочной ошибкой 401 (ошибка 401 — «не авторизован»; доступ запрещён, часто из-за устаревшего пароля).
Скрипт деплоя: один раз написал — используешь годами
Вот где начинается магия. Автор создал скрипт `release.sh`, который автоматизирует весь пайплайн:
- Собирает архив через xcodebuild
- Подписывает Developer ID
- Отправляет на нотаризацию
- Прикрепляет результат проверки
- Устанавливает в /Applications
Основной принцип: один скрипт — один релиз. Написал один раз, потом просто запускаешь.
АВТОМАТИЗАЦИЯ РЕЛИЗА
────────────────────
release.sh ──▶ xcodebuild -archive
│
▼
codesign sign
│
▼
notarytool submit --wait
│
▼
stapler staple
│
▼
cp → /Applications/
│
▼
spctl --verify
Я оценил подход автора: вместо того чтобы объяснять LLM (LLM — большая языковая модель; нейросеть, которая понимает и генерирует текст, как ChatGPT или Claude), что делать, он просто показал готовый скрипт. Модель дополнила параметры (название схемы, team ID, путь для установки) — и вуаля.
Как это работает на практике
Допустим, вы написали приложение для macOS. Что дальше?
## Генерируем проект xcodegen generate ## Собираем xcodebuild -project MyApp.xcodeproj \ -scheme MyApp-macOS \ -configuration Release \ -archivePath build/MyApp.xcarchive \ archive ## Подписываем и экспортируем xcodebuild -exportArchive \ -archivePath build/MyApp.xcarchive \ -exportPath build \ -exportOptionsPlist ExportOptions.plist ## Нотаризуем xcrun notarytool submit build/MyApp.app \ --keychain-profile "MyApp" \ --wait ## Прикрепляем результат xcrun stapler staple build/MyApp.app
Каждая команда возвращает код возврата. Если что-то падает — скрипт останавливается (`set -euo pipefail` (режим строгой обработки ошибок в bash; если любая команда упадёт — скрипт сразу остановится)).
Моя оценка: стоит ли овчинка выделки
Честно? Для большинства разработчиков это overkill. Если вы делаете один-два проекта в год, Xcode вполне сойдёт.
Но! Если вы:
- Автоматизируете CI/CD для Apple-приложений
- Пишете утилиты для внутреннего пользования
- Хотите встроить сборку в существующий пайплайн
- этот подход сэкономит вам кучу времени. Больше никаких «ой, забыл увеличить версию», никаких «ой, не тот сертификат выбрал».
Автор статьи подчёркивает: LLM (типа Claude Code) может написать этот скрипт за вас. Подсунул статью — получил готовый релиз-скрипт. Звучит как идеальное применение AI-ассистентов.
Единственное, что меня напрягает: привязка к app-specific passwords. Они генерируются на сайте Apple, хранятся в ключнике, и живут своей жизнью. Сменили пароль Apple ID — ищете, где что сломалось.
Итог
Xcode — это мощный инструмент. Но для сборки и релизов он не нужен. Терминал, правильные инструменты и один скрипт — всё, что требуется для воспроизводимого процесса.
Если хотите попробовать — начните с XcodeGen. Это самая простая точка входа: создали project.yml, и больше никогда не открываете .xcodeproj руками.
Ссылки
- Building and Shipping Mac and iOS Apps Without Ever Opening Xcode — оригинальная статья Скотта Уилси
- XcodeGen — генератор проектов Xcode
- Apple Developer Program — для нотаризации и дистрибуции
Дмитрий Полухин — продуктовый дизайнер. Пишу про разработку, AI и дизайн интерфейсов. Обо мне, контакты и профили.