Release (релізна збірка) — це фінальна конфігурація мобільного додатку, підготовлена для публікації в магазинах застосунків. Згідно з Apple Developer Documentation, Release-збірка включає оптимізацію коду компілятором, видалення налагоджувальних символів, обфускацію та цифровий підпис дистрибутивним сертифікатом. Основна відмінність від Debug — Release орієнтований на кінцевого користувача, а не на розробника.
Головне
Release — це конфігурація збірки, в якій застосовуються всі оптимізації компілятора, видаляється налагоджувальна інформація, ресурси стискаються, а виконуваний код обфускується для захисту інтелектуальної власності. Мета Release — отримати максимально швидкий і компактний бінарний файл, готовий до розповсюдження через офіційні канали.
На відміну від Debug, Release-збірка не містить точок входу для налагоджувача, твердження вимкнені, а логування зведено до мінімуму. Це не просто перемикання прапорця — це інший пайплайн збірки з іншими сертифікатами, provisioning profile та налаштуваннями пакування. Збірка Release потребує більше часу, оскільки компілятор виконує додаткові проходи оптимізації.
Для iOS Release-збірка підписується Apple Distribution-сертифікатом і проходить перевірку в App Store Connect. Для Android Release-збірка підписується Upload Key і може бути завантажена в Google Play Console. Обидві платформи потребують цифрового підпису: додаток, зібраний без нього, не встановиться на пристрій користувача.
Різниця між Debug і Release проявляється на всіх рівнях: від прапорців компілятора до кінцевого розміру .apk або .ipa. Розуміння цих відмінностей критичне для CI/CD-пайплайну та пошуку регресій, які проявляються тільки в Release-збірці.
У Release компілятор вмикає оптимізацію за розміром (-Os для LLVM) або швидкістю (-O2). Це означає вбудовування inline-функцій, видалення мертвого коду, перестановку інструкцій та агресивну оптимізацію циклів. У Debug всі ці етапи пропускаються, що робить код повільнішим, але зберігає повну відповідність між рядками вихідного коду та машинними інструкціями.
ProGuard/R8 (Android) перейменовують класи, методи та поля в короткі імена (a, b, c), що ускладнює зворотну розробку та зменшує розмір DEX-файлу. На iOS еквівалентна функціональність забезпечується Strip Symbols і Swift Symbolication. Важливо налаштувати правила keep для класів, які використовуються через рефлексію або в XML-розмітці, інакше додаток впаде з ClassNotFoundException на старті.
| Параметр | Android (Gradle) | iOS (Xcode) |
|---|---|---|
| Оптимізація | minifyEnabled true, proguardFiles | Optimization Level: Fastest, Smallest |
| Обфускація | R8 (за замовчуванням) | Strip Linked Product, Symbols Hidden |
| Підпис | Android Signing Config v2/v3 | Apple Distribution Certificate |
| Стиснення ресурсів | shrinkResources true | Asset Catalog Compiler |
| Версіонування | versionCode, versionName | CFBundleVersion, CFBundleShortVersionString |
Release-збірка значно компактніша за Debug. Типове співвідношення: Debug-версія займає 40–80 МБ, Release — 15–30 МБ. Різниця зумовлена видаленням налагоджувальних символів (DWARF), стисненням ресурсів (aapt2) та обфускацією DEX. Для користувачів розмір додатку — важливий фактор конверсії встановлень, тому оптимізація розміру в Release — обов'язкова практика.
Gradle надає вбудовані завдання для збірки Release-версії: assembleRelease, bundleRelease (для AAB) та signingReport. Правильне налаштування build.gradle на рівні модуля — основа стабільної CI/CD-збірки. Розглянемо ключові етапи на прикладі типового проекту.
У buildTypes вказується конфігурація release: вмикається мініфікація, shrinkResources та задаються proguard-правила. Блок signingConfig обов'язково посилається на storeFile, storePassword, keyAlias та keyPassword — ці параметри не повинні зберігатися в VCS. Для CI/CD використовуйте змінні середовища або Keystore Provisioning Plugin.
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile(
"proguard-android-optimize.txt"
), "proguard-rules.pro"
signingConfig signingConfigs.release
}
}
}
Android App Bundle (AAB) — рекомендований формат для публікації в Google Play. AAB містить не один APK, а модульний набір ресурсів, з якого Google Play динамічно генерує оптимізований APK під конкретний пристрій. Команда ./gradlew bundleRelease збирає AAB, а ./gradlew assembleRelease — універсальний APK для тестування перед завантаженням.
Підписаний APK/AAB перевіряється через apksigner verify. Google Play Console автоматично перевіряє підпис при завантаженні. Починаючи з Android 9 (API 28), Google вимагає v2 або v3 схеми підпису. Для Wear OS та Android TV додатково потрібен v3.1 із вказанням rotating key.
Xcode збирає Release-версію в конфігурації Archive — це не просто build, а повний пайплайн: компіляція з оптимізацією, пакування в .xcarchive, підпис Distribution-сертифікатом та експорт в .ipa. Процес ініціюється через Product → Archive або команду xcodebuild.
У Edit Scheme → Run → Build Configuration виберіть Release для фінального тестування. Для відправки в App Store Connect використовуйте Archive з меню Product. Xcode створює .xcarchive, що містить бінарний файл, dSYM та Resource-бандли. З архіву експортується .ipa для Ad Hoc, Development або App Store дистрибуції.
TestFlight приймає Release-збірки, підписані App Store Distribution-сертифікатом. Перед відправкою в App Store збірка проходить автоматичну валідацію в Xcode: перевіряється відповідність сертифікатів, наявність іконок всіх розмірів, коректність Info.plist та відсутність емуляторних архітектур у бінарному файлі.
# Збірка Release через xcodebuild
xcodebuild archive \
-project MyApp.xcodeproj \
-scheme "MyApp" \
-configuration "Release" \
-archivePath "build/MyApp.xcarchive"
# Експорт .ipa для App Store
xcodebuild -exportArchive \
-archivePath "build/MyApp.xcarchive" \
-exportPath "build/" \
-exportOptionsPlist "export.plist"
App Thinning — технологія Apple для зменшення розміру завантажуваного додатку. При завантаженні в App Store Apple перекомпілює бінарний файл під конкретний пристрій користувача, видаляючи невикористовувані архітектури. Bitcode (проміжне представлення LLVM) включається в Release-збірку, якщо проект використовує iOS 14+ та Xcode 12+.
Помилки конфігурації Release-збірки поділяються на три категорії: проблеми компіляції, проблеми підпису та логічні помилки, що проявляються тільки після оптимізації. Розглянемо найпоширеніші сценарії, з якими стикаються розробники при переході від Debug до Release.
Найпоширеніша помилка на Android — падіння при старті після ввімкнення minifyEnabled. Причина: R8 перейменував клас, який використовується через рефлексію (наприклад, Gson серіалізація, Retrofit @Body з data class). Рішення — додати -keep правило для всіх класів, що беруть участь у серіалізації, та перевірити proguard-правила перед збіркою.
На iOS розробники часто забувають зберегти dSYM-файли після Archive. Без dSYM краш-логи з App Store Connect надходять у вигляді шістнадцяткових адрес, а не читабельних імен функцій. Рішення — налаштувати CI/CD на архівування dSYM разом з .ipa та завантаження їх в App Store Connect.
Expired Distribution-сертифікат або невірний App ID у provisioning profile — причина відмови App Store Connect прийняти збірку. Сертифікати діють 1 рік (Apple) або 3 роки (Google), і їх продовження потрібно закладати в релізний календар. Перевірка статусу сертифіката перед кожною Release-збіркою — обов'язковий крок у CI/CD-пайплайні.
Часта проблема при переході від Debug до Release — використання API, недоступних на цільовій версії ОС. У Debug збірка перевіряється на симуляторі з останньою версією, де всі нові API доступні. У Release додаток встановлюється на пристрої користувачів з різними версіями ОС, і виклик unavailable API призводить до crash на старті. Використовуйте @available (Swift) або compileSdkVersion + minSdkVersion (Android) для явного вказання мінімальної версії.
У Debug-збірці ресурси часто завантажуються з вихідних директорій без перевірки конфігурації. У Release Gradle та Xcode застосовують resource filtering: якщо рядок або drawable не знайдено в цільовій локалі, додаток або падає, або показує заповнювач. Особливо це критично для Android: відсутність перекладу в values-XX призводить до ClassCastException при парсингу XML. Перевіряйте всі локалі перед Release-збіркою за допомогою lint та xcodebuild -showBuildSettings. Для виявлення таких проблем використовуйте TestFlight та Internal Testing трек перед публічним релізом — вони запускаються на реальних пристроях з різними мовними налаштуваннями.
Часто задавані питання
Технічно так, якщо встановити на пристрій Ad Hoc Release-збірку з увімкненими символами. Але на практиці це незручно: оптимізований код переставляє інструкції, точки зупинки зміщуються, а локальні змінні можуть бути видалені компілятором.
Симулятор iOS не підтримує всі оптимізації Apple Silicon, тому деякі Release-прапорці (наприклад, LTO) можуть викликати помилки лінкування. Для тестування Release-збірки використовуйте Archive з подальшим експортом на фізичний пристрій.
Split APK — механізм Android для розділення додатку на декілька APK за архітектурою (arm64-v8a, armeabi-v7a, x86). У сучасній розробці замість split APK рекомендується Android App Bundle (AAB), який автоматично створює оптимізовану збірку для кожного пристрою.
Запустіть staging-тестування через TestFlight (iOS) або Internal Testing Track (Google Play). Перевірте авторизацію, платежі, push-сповіщення та роботу з файловою системою — ці сценарії часто ведуть себе по-різному в Debug і Release через різницю в підписі та дозволах.
Використовуйте R8 full mode на Android та App Thinning на iOS. Видаліть невикористовувані ресурси (shrinkResources), замініть PNG на WebP, перевірте залежності на дублікати бібліотек та налаштуйте ProGuard на агресивне видалення мертвого коду.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також