Вопросы про подпись, TestFlight и ревью кажутся организационными, но на них часто проверяют реальный опыт: «вы выпускали приложение сами?».
Подпись кода
Чтобы приложение запустилось на устройстве, его код подписывается:
- Сертификат подтверждает, кто подписал. Development для отладки, Distribution для TestFlight и App Store. Приватный ключ хранится у разработчика или в CI.
- Provisioning profile связывает App ID, разрешённые сертификаты, entitlements и (для development и ad hoc) список устройств.
- Entitlements это подписанные разрешения на системные возможности: push, App Groups, iCloud, Sign in with Apple, Associated Domains. Они должны совпадать с профилем, иначе ошибка подписи.
Автоматическая подпись Xcode удобна локально. На CI используют ключ App Store Connect API и общее хранилище сертификатов (например, fastlane match) или Xcode Cloud.
Версия и номер сборки
CFBundleShortVersionString(Version): то, что видит пользователь, например 2.4.CFBundleVersion(Build): должен расти с каждой загрузкой в пределах версии. Загрузить дважды 2.4 (17) нельзя, нужен 2.4 (18).
Версии сравнивают покомпонентно: 1.10 больше 1.9, хотя как строки наоборот.
Конфигурации и окружения
Build configurations (Debug, Release и свои, например Staging) со своими .xcconfig задают Bundle ID, имя, иконку, адрес API и флаги компиляции. Схема выбирает конфигурацию для запуска и архивации. Так нельзя случайно выпустить сборку с тестовым сервером.
Зависимости
Swift Package Manager встроен в Xcode и стал основным способом подключения библиотек: поддерживает бинарные XCFramework, ресурсы и плагины. CocoaPods ушёл в режим поддержки, Carthage встречается в старых проектах.
Если вы распространяете закрытый бинарный SDK, включите BUILD_LIBRARY_FOR_DISTRIBUTION: появится .swiftinterface, и фреймворк смогут подключать проекты на более новом Swift.
TestFlight
- Внутренние тестировщики (до 100 участников команды) получают сборку без проверки.
- Внешние (до 10 000) после Beta App Review, можно раздать публичной ссылкой.
- Сборка доступна 90 дней.
App Review
Частые причины отклонения:
- крэши и недоделанный функционал, плейсхолдеры;
- ревьюер не может войти: нужен демо-аккаунт или демо-режим без SMS на местный номер, шаги в заметках для ревью;
- обход In-App Purchase: цифровой контент и функции внутри приложения продаются через IAP (правило 3.1.1), физические товары и услуги вне приложения можно оплачивать иначе; есть региональные исключения, их проверяют для своей ситуации;
- нет удаления аккаунта, если приложение позволяет его создать (требование с 2022 года);
- непонятные тексты запросов разрешений (
NSCameraUsageDescriptionи др.); - неполные метаданные и скриншоты.
Скрывать функциональность на время ревью нельзя: это нарушение правил с риском блокировки аккаунта разработчика.
Приватность
- Privacy manifest (
PrivacyInfo.xcprivacy): с мая 2024 обязателен для приложений и SDK, использующих required reason API (UserDefaults, время загрузки системы, свободное место на диске, даты файлов и другие). Для каждого API указывается допустимая причина. - Privacy Nutrition Labels в App Store Connect описывают собираемые данные.
- App Tracking Transparency: трекинг между приложениями только после согласия пользователя.
Выпуск
- Поднять версию и номер сборки.
- Собрать архив с подписью для распространения.
- Загрузить в App Store Connect (Xcode,
xcodebuild+altool/Transporter, fastlane). - Проверить в TestFlight.
- Отправить версию на ревью.
- Выпустить вручную, по дате или поэтапно.
Поэтапный релиз растягивает автообновление на 7 дней (примерно 1%, 2%, 5%, 10%, 20%, 50%, 100% пользователей). Вручную обновиться может любой. Раскатку можно приостановить, если вырос процент крэшей.
dSYM загружают в крэш-аналитику для каждой релизной сборки, иначе стеки будут адресами. Bitcode не поддерживается с Xcode 14.
Срочный фикс: запрос ускоренного ревью, а заранее фича-флаги, чтобы выключить проблемную функцию без нового релиза.
Принудительное обновление
Сервер или удалённый конфиг отдаёт минимальную и рекомендуемую версии. Ниже минимальной клиент показывает блокирующий экран со ссылкой в App Store, ниже рекомендуемой мягкое предложение. Это крайняя мера: лучше версионировать API и поддерживать старые клиенты.
Что спросят на собесе
- Что такое сертификат, provisioning profile и entitlements?
- Чем версия отличается от номера сборки?
- Как устроен ваш релизный процесс, TestFlight, поэтапный релиз?
- Почему приложение могут отклонить и как этого избежать?
- Что такое privacy manifest и required reason API?