Публикация в App Store и Google Play
Версионирование, подпись, тестовые треки, правила ревью и rollout — без сюрпризов.
За 30 секунд
Публикация мобильного приложения означает: собрать подписанную сборку, загрузить её в App Store Connect или Play Console, протестировать с реальными пользователями, пройти ревью и выкатить. У каждого стора свои правила для версий, ключей подписи, информации о приватности и контента. Записанный, воспроизводимый процесс релиза превращает напряжённый день в рутину.
Почему я это использую
- Я уделяю внимание release engineering, потому что отличное приложение, которое нельзя надёжно выпустить, ничего не стоит для клиента.
- Отказы на ревью и проблемы с подписью стоят дней; я лучше предотвращу их чек-листом, чем буду исправлять под давлением дедлайна.
- Поэтапные rollout и переключатель принудительного обновления позволяют выпускать релизы уверенно и остановить плохую сборку до того, как она дойдёт до всех.
- Я документирую процесс релиза для каждого приложения, чтобы выпустить его мог любой инженер в команде, а не только тот, кто всё настраивал.
Как это работает
01Версионирование: имя версии и номер сборки
У каждой сборки два числа. Версия для пользователя (на iOS CFBundleShortVersionString, на Android versionName) следует семантическому версионированию: 2.4.0 для релиза с новыми функциями, 2.4.1 для исправления. Номер сборки (на iOS CFBundleVersion, на Android versionCode) нужен сторам и всегда должен расти: Google Play отклоняет versionCode, который уже видел, а App Store Connect требует уникальный номер сборки для каждой версии. Держите один источник истины и позвольте CI увеличивать номер сборки, например по номеру запуска пайплайна. Помечайте git-коммит тегом с версией, чтобы всегда можно было пересобрать то, что лежит в сторе. И помните, что OTA-обновления (если вы их используете) должны быть привязаны к runtime version, чтобы JavaScript-обновление никогда не попало на бинарник с другим нативным кодом.
// android/app/build.gradle
android {
defaultConfig {
versionCode 2041 // integer, must always increase
versionName "2.4.1" // shown to users
targetSdk 36 // Play: API 36 for new apps and updates from Aug 31, 2026
}
}
// iOS (Xcode build settings):
// MARKETING_VERSION = 2.4.1 -> CFBundleShortVersionString
// CURRENT_PROJECT_VERSION = 2041 -> CFBundleVersion
02Подпись: сертификаты и профили iOS, keystore Android
Подпись доказывает, что сборка сделана вами и не была изменена. На iOS нужны членство в Apple Developer Program, App ID (bundle identifier), сертификат распространения (приватный ключ в вашем keychain или в CI) и provisioning profile, который связывает сертификат, App ID и capabilities (push, Sign in with Apple, associated domains). Автоматическая подпись в Xcode подходит небольшим командам; в CI обычно используют fastlane match или учётные данные EAS, чтобы безопасно ими делиться. На Android вы подписываете сборку upload key из файла keystore; с Play App Signing (обязательно для новых приложений, которые выпускаются как AAB-бандлы) настоящий ключ подписи приложения хранит Google и переподписывает сборки. Если вы потеряете upload key, можно запросить его сброс; без Play App Signing потеря ключа означала, что приложение больше никогда нельзя обновить. Никогда не коммитьте keystore или пароли в git; храните их в менеджере секретов или в секретах CI.
# Create an Android upload key (keep the file and passwords in a secret store)
keytool -genkeypair -v -keystore upload-key.jks -alias upload \
-keyalg RSA -keysize 2048 -validity 10000
# Build a signed Android App Bundle
cd android && ./gradlew bundleRelease
# iOS: archive and upload with fastlane (certificates via match)
bundle exec fastlane ios beta
03Тестовые треки: TestFlight и тестирование в Play
Никогда не отправляйте в продакшен сборку, которую реальные люди не устанавливали через собственный конвейер стора. На iOS загрузите сборку в App Store Connect и используйте TestFlight: внутренние тестировщики (члены вашей команды) получают сборки почти сразу; внешние тестировщики (до 10,000, по email или публичной ссылке) требуют короткого бета-ревью для первой сборки версии. Сборки истекают через 90 дней. На Android в Play Console есть internal testing (быстро, до 100 тестировщиков), closed testing (списки или группы) и open testing. Обратите внимание: новые личные аккаунты разработчиков должны провести закрытый тест как минимум с 12 тестировщиками, участвующими 14 дней подряд, прежде чем смогут запросить доступ к продакшену; аккаунты организаций от этого освобождены. Тестируйте release-сборку, а не только debug: минификация, подпись, push и deep links часто ведут себя по-другому.
- Тестируйте обновление с предыдущей версии из стора, а не только чистую установку
- Проверяйте push, deep links, платежи и вход на release-сборке
- Держите наготове аккаунт для ревью/демо с примерами данных
04Страницы в сторах и информация о приватности
Страница в сторе продаёт приложение и заодно заявляет факты, которые сторы проверяют. Нужны название, подзаголовок/короткое описание, описание, ключевые слова (iOS), скриншоты для обязательных размеров устройств, иконка, категория, анкета возрастного рейтинга, URL поддержки и URL политики конфиденциальности. Оба стора требуют раскрытия информации о приватности: «этикетки» App Privacy от Apple и форма Data safety в Google Play должны соответствовать тому, что на самом деле собирают приложение и его SDK (аналитика, отчёты о падениях, платежи). На iOS приложения и сторонние SDK должны включать privacy manifests с описанием использования данных и API с «required reason». Если приложение отслеживает пользователей в приложениях или на сайтах других компаний, нужно использовать App Tracking Transparency. Локализуйте страницы для каждого целевого рынка. Готовьте скриншоты с реальной сборки на реалистичных, неперсональных демо-данных.
05Правила ревью и частые причины отказов
Apple проверяет каждую версию по App Review Guidelines; Google сочетает автоматические проверки с ревью на соответствие политикам. Большинство отказов предсказуемы. Падения или сломанные сценарии во время ревью. Отсутствие демо-аккаунта или экран входа, который ревьюеры не могут пройти. Создание аккаунта без возможности удалить его внутри приложения (Apple этого требует). Вход через сторонние соцсети без равноценного варианта с упором на приватность, такого как Sign in with Apple. Продажа цифровых товаров или подписок в обход in-app purchase там, где он обязателен (физические товары и реальные услуги, например заказ еды, используют обычных платёжных провайдеров). Запросы разрешений без понятных purpose strings. Контент-заглушки, битые ссылки или приложение, которое является просто обёрткой над сайтом. Этикетки приватности, не соответствующие SDK. Отвечайте спокойно и по существу в Resolution Center; многие отказы снимаются объяснением или коротким видео.
- Предоставьте рабочий демо-аккаунт и заметки для ревьюера
- Дайте возможность удалить аккаунт внутри приложения, если пользователи могут его создавать
- Пишите конкретные purpose strings для разрешений (камера, геолокация, фото)
- Держите сборки для стора на актуальных SDK: Apple и Google ежегодно поднимают минимальные требования
06Поэтапные rollout, хотфиксы и OTA-обновления
Не выпускайте релиз сразу на 100%. На iOS Phased Release распределяет автоматические обновления на семь дней (1%, 2%, 5%, 10%, 20%, 50%, 100%) и может быть поставлен на паузу; пользователи всё равно могут обновиться вручную. В Google Play staged rollout позволяет выбрать процент и увеличивать его или остановить, если Crashlytics показывает всплеск. Перед каждым шагом смотрите на crash-free users, ключевые воронки и сообщения в поддержку. На случай аварий держите ветку для хотфиксов и запросы на ускоренное ревью (используйте их экономно), плюс kill-switches в Remote Config. OTA-обновления (EAS Update или self-hosted аналоги; сервис CodePush от Microsoft был закрыт вместе с App Center в 2025) заменяют JavaScript-бандл и ассеты без ревью в сторе. Они отлично подходят для небольших исправлений, но не могут менять нативный код, должны соответствовать runtime version бинарника и не должны менять основное назначение приложения — правила сторов по-прежнему действуют. OTA-обновления тоже выкатывайте постепенно.
Когда применять
- Каждый публичный релиз для iOS или Android, начиная с самого первого.
- Внутренние и корпоративные приложения, распространяемые через TestFlight или приватные треки Play.
- Ситуации с хотфиксами, где подготовленный процесс и контроль rollout важнее всего.
Когда не стоит
- Чистые веб-приложения или PWA, которым не нужно присутствие в сторах.
- Очень ранние прототипы — делитесь development builds или внутренними треками, прежде чем вкладываться в полноценные страницы в сторах.
Альтернативы
- EAS Build & Submit
Облачный сервис Expo, который собирает, подписывает и отправляет приложения для iOS и Android.
- fastlane
Open-source автоматизация подписи, сборки, скриншотов и загрузок, запускается локально или в CI.
- Firebase App Distribution
Распространение предрелизных сборок среди тестировщиков вне сторов.
- Корпоративное / MDM распространение
Custom apps через Apple Business Manager или managed Google Play для внутренних приложений компании.
Лучшие практики
- Ведите письменный чек-лист релиза для каждого приложения, версионируемый вместе с кодом.
- Позвольте CI увеличивать номера сборок и ставить тег на git-коммит для каждой сборки в стор.
- Храните ключи подписи и пароли в менеджере секретов; включите Play App Signing.
- Тестируйте подписанную release-сборку через TestFlight или внутренний трек, включая обновление с предыдущей версии.
- Синхронизируйте этикетки приватности, Data safety и privacy manifests с каждым добавленным SDK.
- Используйте phased/staged rollout и смотрите на crash-free users перед увеличением процента.
- Добавьте переключатель принудительного обновления и поддержку удаления аккаунта внутри приложения с первого релиза.
Частые ошибки
- Повторно использовать или уменьшать номер сборки, из-за чего загрузку отклоняют в последний момент.
- Потерять ключ подписи или хранить его на одном ноутбуке без резервной копии.
- Отправлять на ревью без демо-аккаунта или с входом, который ревьюеры не могут пройти.
- Добавить SDK аналитики или рекламы, не обновив этикетки приватности и форму Data safety.
- Выкатить OTA-обновление, которое зависит от нативного кода, отсутствующего в установленном бинарнике.
Глубже
07CI-пайплайн, который собирает, подписывает и загружает
Ручные релизы ломаются скучным образом: не та scheme, истёкший сертификат на одном ноутбуке, забытый номер сборки. Перенесите весь путь в CI. Для iOS fastlane match хранит сертификаты и профили в зашифрованном виде в приватном репозитории, а CI забирает их только для чтения; ключ App Store Connect API заменяет вход через личный Apple ID и запросы двухфакторной аутентификации. Для Android CI расшифровывает upload keystore из секрета, собирает AAB и загружает его во внутренний трек. Номера сборок берутся из номера запуска пайплайна, коммит помечается тегом, а job сохраняет артефакты сборки и файлы символов. За людьми остаются решения, требующие суждения, — продвижение в production и увеличение процента раскатки, — а машины выполняют каждый повторяемый шаг.
# fastlane/Fastfile
platform :ios do
lane :beta do
setup_ci
app_store_connect_api_key(key_id: ENV["ASC_KEY_ID"], issuer_id: ENV["ASC_ISSUER_ID"],
key_content: ENV["ASC_KEY_P8"])
match(type: "appstore", readonly: true)
increment_build_number(build_number: ENV["CI_RUN_NUMBER"])
build_app(scheme: "MyApp", export_method: "app-store")
upload_to_testflight(skip_waiting_for_build_processing: true)
end
end
platform :android do
lane :internal do
gradle(task: "bundle", build_type: "Release", project_dir: "android")
upload_to_play_store(track: "internal", aab: lane_context[SharedValues::GRADLE_AAB_OUTPUT_PATH])
end
end
08Требования платформ меняются каждый год
Оба стора поднимают минимальные требования в ежегодном ритме, и релиз может заблокировать правило, не имеющее никакого отношения к вашей функции. Apple: с 28 апреля 2026 App Store Connect принимает только сборки, сделанные в Xcode 26 с iOS 26 SDK или новее; privacy manifest и заявленные причины использования чувствительных API проверяются при загрузке. Google: новые приложения и обновления должны таргетировать API 36 с 31 августа 2026, а приложения, таргетирующие Android 15 или выше, должны поддерживать страницы памяти размером 16 KB — значит, нативные библиотеки, включая те, что внутри зависимостей React Native, должны быть собраны с учётом этого. Планируйте фиксированное окно обновлений каждый год (Xcode, Android Gradle Plugin, React Native, SDK), а не узнавайте о правиле во время срочного hotfix, и подпишитесь на новости для разработчиков от Apple и Google.
09Что сторы делают с вашим бинарником
На Android вы загружаете App Bundle, а не APK. Google Play разбивает его на APK под каждую конфигурацию устройства — архитектуру CPU, плотность экрана, язык — и подписывает их ключом app signing, поэтому пользователи скачивают только то, что нужно их устройству. bundletool позволяет воспроизвести эти APK локально и протестировать ровно то, что установит устройство. На iOS App Store Connect обрабатывает загрузку, а App Thinning создаёт варианты под конкретные устройства; отчёт о размере в App Store Connect показывает реальные размеры загрузки и установки по устройствам. Размер влияет на конверсию, особенно в мобильном интернете: следите за нативными библиотеками, встроенными шрифтами и изображениями и неиспользуемыми локалями. Оба стора также запускают автоматические проверки при загрузке — использование приватных API, отсутствующие purpose strings, проблемы privacy manifest, target SDK, — и эти сообщения приходят по email, так что кто-то должен их читать.
# Reproduce what Play would install on the connected device
bundletool build-apks --bundle=app-release.aab --output=app.apks --connected-device
bundletool install-apks --apks=app.apks
# Check which certificate signed an APK
apksigner verify --print-certs app.apk
# Fingerprints of your upload key (needed for API consoles and resets)
keytool -list -v -keystore upload-key.jks -alias upload
10OTA-обновления: runtime version, каналы и откат
OTA-обновление безопасно только тогда, когда оно попадает на бинарник ровно с тем нативным кодом, которого ожидает. EAS Update отслеживает это через runtime version. Политика appVersion привязывает её к версии приложения: это просто, но ломается, если кто-то меняет нативный код, не повышая версию; политика fingerprint хэширует нативный проект, поэтому любое нативное изменение автоматически даёт новый runtime — ценой более частых сборок для стора. Сборки слушают канал (production, staging), привязанный к ветке обновлений, поэтому обновление можно протестировать на staging-сборках, прежде чем направить на него production. Раскатывайте постепенно по проценту, следите за crash-free users и держите путь отката: повторно опубликуйте предыдущее обновление или откатитесь к обновлению, встроенному в бинарник. Подписывайте обновления (code signing), чтобы скомпрометированный сервер не мог отправить произвольный код.
# app.json (expo): runtime changes whenever native code changes
# "runtimeVersion": { "policy": "fingerprint" }
# Publish to 10% of production users first
eas update --branch production --message "Fix checkout crash" --rollout-percentage 10
# Increase, finish or revert the rollout
eas update:edit
eas update:revert-update-rollout
# Emergency: send clients back to the code embedded in the binary
eas update:roll-back-to-embedded
Реальные ситуации
Отказ из-за отсутствия удаления аккаунта
Проблема
Новую версию отклонили по пункту 5.1.1(v) App Review Guidelines: пользователи могут создать аккаунт в приложении, но не могут его удалить. Релиз обещан клиенту на понедельник.
Как решить
Добавьте понятный путь, обычно «Настройки → Аккаунт → Удалить аккаунт», который запускает удаление внутри приложения, — одной ссылки на email-адрес недостаточно. Попросите пользователя подтвердить, объясните, что произойдёт с его данными и заказами, и если законодательство требует хранить часть записей (счета), так и скажите. Бэкенд должен действительно удалить или анонимизировать персональные данные, отозвать токены и удалить push-токены, возможно, после короткого льготного периода. Если приложение использует Sign in with Apple, отзовите токен через REST API Apple. Выпустите исправление с заметками для ревьюера о том, где находится опция, приложите короткую запись экрана и ответьте в Resolution Center, указав номер сборки.
Всплеск крашей на раскатке 10%
Проблема
Версия 3.2.0 ушла на 10% пользователей Android и на 1% в phased release на iOS. За несколько часов Crashlytics показывает падение crash-free users с 99.8% до 97% на новом экране оплаты.
Как решить
Немедленно остановите staged rollout в Play и приостановите phased release на iOS; у пользователей, которые уже обновились, сборка останется, поэтому выключите новый экран оплаты его флагом в Remote Config, чтобы защитить их. Изучите сгруппированный issue в Crashlytics, воспроизведите проблему на затронутой модели устройства, исправьте в hotfix-ветке от тега релиза и поднимите версию до 3.2.1 с более высоким номером сборки. Протестируйте исправление через TestFlight и внутренний трек, включая обновление с 3.2.0. Запросите expedited review на iOS, если масштаб проблемы это оправдывает. Возобновите раскатку с низкого процента и напишите короткую заметку об инциденте: что сломалось, почему тесты это пропустили и какую проверку добавить.
Upload key для Android потерян
Проблема
Единственный разработчик, у которого был upload keystore, ушёл из компании, и никто не знает пароль. CI не может подписывать новые сборки, а исправление безопасности нужно выпустить на этой неделе.
Как решить
С Play App Signing приложение не потеряно — ключ app signing хранится у Google. Сгенерируйте новый upload key через keytool, экспортируйте его сертификат командой keytool -export -rfc -keystore new-upload.jks -alias upload -file upload_certificate.pem и попросите владельца аккаунта запросить сброс upload key в Play Console в разделе App integrity, приложив этот PEM-файл. После подтверждения от Google (это может занять несколько дней) подписывайте сборки новым ключом. Обновите все консоли API, которые используют отпечаток upload key, например ограничения Google sign-in или Maps. Затем устраните первопричину: keystore и пароли — в командном secret store с доступом как минимум у двух человек.
Шпаргалка
- Задать номер сборки iOS из CLI
agvtool new-version -all 2042- Собрать подписанный Android App Bundle
cd android && ./gradlew bundleRelease- Экспортировать upload-сертификат для сброса ключа
keytool -export -rfc -keystore upload-key.jks -alias upload -file upload_certificate.pem- Проверить сертификат подписи APK
apksigner verify --print-certs app.apk- Загрузить в TestFlight через fastlane
bundle exec fastlane pilot upload- Загрузить AAB во внутренний трек Play
bundle exec fastlane supply --aab app-release.aab --track internal- Собрать и отправить через EAS
eas build --platform all --profile production && eas submit --platform ios- Опубликовать постепенное OTA-обновление
eas update --branch production --message "Fix" --rollout-percentage 10- Постепенный релиз на iOS
App Store Connect → version → Phased Release for Automatic Updates- Постепенный релиз на Android
Play Console → Production → Create release → staged rollout %
В моих реальных проектах
- Я веду задокументированный процесс релиза для мобильных приложений, которые выпускаю, включая переключатели принудительного обновления и техработ в Remote Config.
- Мои приложения поддерживают deep links через Universal Links и Android App Links, а файлы ассоциации отдаются соответствующими сайтами.
- Инвестиционное приложение, над которым я работал, включает удаление аккаунта внутри приложения, настройки согласий, офлайн-баннер и принудительное обновление.
Вопросы и ответы
Q1В чём разница между версией и номером сборки?
Версия, например 2.4.1, — это то, что видят пользователи, и она следует семантическому версионированию. Номер сборки идентифицирует один загруженный бинарник и должен постоянно расти: на Android versionCode — целое число, которое никогда не может повторяться, а на iOS каждой сборке версии нужен уникальный CFBundleVersion. Пока вы исправляете баги, можно загрузить в TestFlight несколько сборок 2.4.1, каждую с большим номером, и выпустить только одну. Я позволяю CI задавать номер сборки автоматически и ставлю тег на коммит, чтобы каждую сборку в сторе можно было отследить и пересобрать.
Q2Что будет, если потерять ключ подписи Android?
Зависит от того, использует ли приложение Play App Signing. С ним — а для новых приложений, выпускаемых как App Bundle, это обязательно — Google хранит ключ подписи приложения, а у вас только upload key. Если вы потеряете upload key, владелец аккаунта может запросить его сброс в Play Console и продолжить публикацию. Без Play App Signing потеря ключа означала, что приложение больше никогда нельзя обновить, и приходилось публиковать новую страницу в сторе. Поэтому я всегда его включаю и храню upload keystore и пароли в менеджере секретов с резервной копией.
Q3Какие самые частые причины отказа в App Store и как их избежать?
Падения и сломанные функции во время ревью, отсутствие демо-доступа, неполные метаданные или контент-заглушки, отсутствие удаления аккаунта внутри приложения, этикетки приватности, не соответствующие SDK, непонятные purpose strings для разрешений и использование внешних платежей для цифрового контента, где требуется in-app purchase. Я избегаю их с помощью чек-листа перед отправкой: тестирую release-сборку через TestFlight, предоставляю демо-аккаунт и заметки для ревьюера, проверяю каждую строку разрешений, поддерживаю информацию о приватности актуальной и слежу, чтобы варианты входа соответствовали правилу о логине. При отказе отвечаю в Resolution Center точными фактами.
Q4Как безопасно выкатить релиз?
Сначала сборка проходит через внутренних тестировщиков в TestFlight и внутренний трек Play, включая обновление с предыдущей версии. Затем я использую Phased Release от Apple и staged rollout в Play, начиная с небольшого процента. Перед каждым увеличением проверяю crash-free users в Crashlytics, логи ошибок и бизнес-метрики вроде завершённых заказов. Если что-то не так, ставлю rollout на паузу и отключаю затронутую функцию через Remote Config, пока исправление проходит ревью. Переключатель принудительного обновления — последнее средство, если старая версия должна перестать работать.
Q5Разрешены ли OTA-обновления и когда вы их используете?
Да, в определённых рамках. Apple и Google разрешают обновлять интерпретируемый код, такой как JavaScript-бандл, если обновление не меняет основное назначение приложения, не добавляет функции в обход ревью и не нарушает правила сторов. Технически OTA-обновление может менять только JavaScript и ассеты, но никогда не нативный код, поэтому оно должно быть нацелено на соответствующую runtime version установленного бинарника. Я использую OTA для срочных исправлений багов и правок текстов, выкатывая их постепенно и с планом отката. Новые функции и всё, что затрагивает нативные модули, по-прежнему идёт через сторы.
Вопросы уровня senior
S1Как сохранить совместимость бэкенда со старыми версиями приложения?
Исходите из того, что каждая когда-либо выпущенная версия где-то ещё используется. Изменения API следуют схеме expand-and-contract: сначала добавьте новые поля и endpoint, сохраните работу старых, выпустите приложения, использующие новую структуру, и удаляйте старую только тогда, когда аналитика показывает, что оставшиеся старые версии пренебрежимо малы. Клиенты передают версию приложения и платформу в заголовках, поэтому бэкенд может измерять использование, применять поведение под конкретную версию и возвращать понятную ошибку «требуется обновление». Remote Config хранит минимальную поддерживаемую версию для принудительного обновления — это крайняя мера, а не план, потому что оно прерывает пользователей. Компромисс — месяцами носить код совместимости; я фиксирую каждую временную прослойку с условием её удаления, чтобы её действительно удалили.
S2Спроектируйте процесс релиза для пяти приложений, построенных на одном шаблоне.
Стандартизируйте пайплайн, а не приложения. У каждого приложения одинаковая конфигурация fastlane или EAS, сгенерированная из шаблона, а специфичные значения — bundle ID, signing identity, метаданные стора, URL окружений — лежат в небольшом конфиг-файле, секреты — в CI. Один общий чеклист покрывает версионирование, privacy labels, демо-аккаунты, smoke-тесты release-сборки и шаги раскатки; каждое приложение добавляет только свои особые случаи. Изменения шаблона, например обновление SDK, сначала проходят через внутренние треки одного пилотного приложения, а затем раскатываются на остальные. Каждый релиз помечается тегом и имеет короткий changelog. Компромисс: единообразие иногда задерживает одно приложение в ожидании общего изменения, зато любой инженер может выпустить любое приложение, а изменение правил стора исправляется один раз, а не пять.
S3Когда OTA-обновление — неправильный инструмент, даже если технически оно возможно?
Когда оно существенно меняет то, что одобрил ревьюер, — новый процесс оплаты, новый раздел функций, изменение назначения приложения, — потому что правила сторов разрешают обновления интерпретируемого кода только в определённых пределах, а их нарушение грозит удалением приложения. Когда исправление зависит от нативного кода, нового разрешения или изменённого SDK, потому что runtime version не совпадёт. Когда обновление большое или изменение достаточно рискованное, чтобы безопаснее была поэтапная раскатка через стор с мониторингом крашей. И когда у команды нет дисциплины отката: ошибка в OTA доходит до пользователей за минуты. Я использую OTA для исправления багов, текстов и небольших правок вёрстки — всегда с постепенной раскаткой, подписанными обновлениями и проверенным путём отката — и держу письменное правило, что под это подходит.
Глоссарий
- Bundle identifier
- Уникальный ID iOS-приложения в формате обратного домена, например com.example.shop; после релиза его нельзя изменить.
- Provisioning profile
- Файл Apple, связывающий сертификат, App ID и capabilities и позволяющий установить или выпустить сборку.
- Distribution certificate
- Сертификат Apple с приватным ключом, которым подписываются сборки для TestFlight и App Store.
- Upload key
- Ключ, которым вы подписываете Android-бандлы перед загрузкой; Google проверяет его и переподписывает бандл ключом app signing.
- Play App Signing
- Google хранит ваш ключ app signing и подписывает доставляемые APK, поэтому потерянный upload key можно восстановить.
- AAB
- Android App Bundle: формат загрузки, из которого Google Play генерирует оптимизированные APK для каждого устройства.
- Phased release
- Семидневная постепенная раскатка автоматических обновлений от Apple, которую можно приостановить суммарно до 30 дней.
- Runtime version
- Метка, описывающая нативный код бинарника, чтобы OTA-обновления попадали только на совместимые сборки.
- Privacy manifest
- Файл PrivacyInfo.xcprivacy, в котором указано, какие данные собирает приложение или SDK и зачем оно использует определённые API.
- Expedited review
- Запрос к Apple ускорить ревью сборки; предназначен для критических исправлений и событий, привязанных ко времени.
Что изучить дальше
Есть идея продукта?Давайте создадим его.
Расскажите о своей идее, продукте или команде. Обычно отвечаю в течение одного рабочего дня.