Release (بیلد انتشار) — پیکربندی نهایی برنامه موبایل است که برای انتشار در فروشگاههای برنامه آماده شده است. به گفته Apple Developer Documentation، بیلد Release شامل بهینهسازی کد توسط کامپایلر، حذف نمادهای اشکالزدایی، مبهمسازی و امضای دیجیتال با گواهی توزیع است. تفاوت اصلی با Debug — Release برای کاربر نهایی طراحی شده است، نه برای توسعهدهنده.
نکات کلیدی
Release — پیکربندی بیلدی است که در آن تمام بهینهسازیهای کامپایلر اعمال میشود، اطلاعات اشکالزدایی حذف میگردد، منابع فشرده میشوند و کد اجرایی برای محافظت از مالکیت معنوی مبهمسازی میشود. هدف Release به دست آوردن سریعترین و فشردهترین فایل باینری آماده برای توزیع از طریق کانالهای رسمی است.
برخلاف Debug، بیلد Release شامل نقاط ورود برای دیباگر نیست، تأییدیهها غیرفعال هستند و لاگگیری به حداقل رسیده است. این فقط تغییر یک پرچم نیست — این یک pipeline بیلد متفاوت با گواهیها، provisioning profile و تنظیمات بستهبندی متفاوت است. بیلد Release زمان بیشتری میبرد زیرا کامپایلر مراحل بهینهسازی اضافی را انجام میدهد.
برای iOS بیلد Release با گواهی Apple Distribution امضا میشود و در App Store Connect تأیید میگردد. برای Android بیلد Release با کلید Upload Key امضا میشود و میتواند در Google Play Console بارگذاری شود. هر دو پلتفرم نیاز به امضای دیجیتال دارند: برنامهای که بدون آن ساخته شده باشد روی دستگاه کاربر نصب نخواهد شد.
تفاوت بین Debug و Release در همه سطوح ظاهر میشود: از پرچمهای کامپایلر تا اندازه نهایی .apk یا .ipa. درک این تفاوتها برای pipeline CI/CD و یافتن بازگشتهایی که فقط در بیلد Release ظاهر میشوند حیاتی است.
در Release کامپایلر بهینهسازی بر اساس اندازه (-Os برای LLVM) یا سرعت (-O2) را فعال میکند. این به معنای جایگذاری توابع inline، حذف کد مرده، مرتبسازی مجدد دستورالعملها و بهینهسازی تهاجمی حلقهها است. در Debug تمام این مراحل رد میشوند که کد را کندتر میکند اما تطابق کامل بین خطوط کد منبع و دستورالعملهای ماشین را حفظ میکند.
ProGuard/R8 (Android) نام کلاسها، متدها و فیلدها را به نامهای کوتاه (a, b, c) تغییر میدهند که مهندسی معکوس را دشوارتر کرده و اندازه فایل DEX را کاهش میدهد. در iOS عملکرد معادل توسط Strip Symbols و Swift Symbolication ارائه میشود. تنظیم قوانین keep برای کلاسهایی که از طریق reflection یا در طرح 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 MB، Release — 15–30 MB فضا اشغال میکند. تفاوت ناشی از حذف نمادهای اشکالزدایی (DWARF)، فشردهسازی منابع (aapt2) و مبهمسازی DEX است. برای کاربران، اندازه برنامه عامل مهمی در نرخ تبدیل نصب است، بنابراین بهینهسازی اندازه در Release یک روش الزامی است.
Gradle وظایف داخلی برای ساخت نسخه Release ارائه میدهد: assembleRelease، bundleRelease (برای AAB) و signingReport. پیکربندی صحیح build.gradle در سطح ماژول اساس یک بیلد CI/CD پایدار است. مراحل کلیدی را با مثال یک پروژه معمولی بررسی میکنیم.
در buildTypes پیکربندی release مشخص میشود: minification فعال میشود، 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 نیست، بلکه یک pipeline کامل است: کامپایل با بهینهسازی، بستهبندی در .xcarchive، امضا با گواهی Distribution و صدور به .ipa. فرآیند از طریق Product → Archive یا دستور xcodebuild آغاز میشود.
در Edit Scheme → Run → Build Configuration برای تست نهایی Release را انتخاب کنید. برای ارسال به App Store Connect از Archive در منوی Product استفاده کنید. Xcode یک .xcarchive شامل فایل باینری، dSYM و Resource-bundle ایجاد میکند. از آرشیو یک .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 — فناوری اپل برای کاهش اندازه برنامه دریافتی است. هنگام بارگذاری در App Store، اپل فایل باینری را برای دستگاه خاص کاربر دوباره کامپایل میکند و معماریهای استفاده نشده را حذف میکند. Bitcode (نمایش میانی LLVM) در بیلد Release فعال میشود اگر پروژه از iOS 14+ و Xcode 12+ استفاده کند.
اشتباهات پیکربندی بیلد Release به سه دسته تقسیم میشوند: مشکلات کامپایل، مشکلات امضا و خطاهای منطقی که فقط پس از بهینهسازی ظاهر میشوند. بیایید سناریوهای رایجی که توسعهدهندگان هنگام انتقال از Debug به Release با آن مواجه میشوند را بررسی کنیم.
رایجترین خطا در Android — از کار افتادن در شروع پس از فعالسازی minifyEnabled. دلیل: R8 نام کلاسی را که از طریق reflection استفاده میشود تغییر داده است (مثلاً Gson serialization، Retrofit @Body با data class). راهحل — یک قانون -keep برای تمام کلاسهای شرکتکننده در سریالسازی اضافه کنید و قوانین proguard را قبل از بیلد بررسی کنید.
در iOS توسعهدهندگان اغلب فراموش میکنند فایلهای dSYM را پس از Archive ذخیره کنند. بدون dSYM گزارشهای خرابی از App Store Connect به صورت آدرسهای هگزادسیمال میآیند نه نامهای خوانا. راهحل — CI/CD را برای بایگانی dSYM به همراه .ipa و بارگذاری آنها در App Store Connect پیکربندی کنید.
گواهی Distribution منقضی شده یا App ID نادرست در provisioning profile — دلیل رد بیلد توسط App Store Connect. گواهیها 1 سال (Apple) یا 3 سال (Google) اعتبار دارند و تمدید آنها باید در تقویم انتشار لحاظ شود. بررسی وضعیت گواهی قبل از هر بیلد Release یک گام اجباری در pipeline CI/CD است.
مشکل رایج در انتقال از Debug به Release — استفاده از APIهای موجود در نسخه هدف سیستم عامل. در Debug بیلد روی شبیهساز با آخرین نسخه آزمایش میشود که همه APIهای جدید در دسترس هستند. در Release برنامه بر روی دستگاههای کاربران با نسخههای مختلف سیستم عامل نصب میشود و فراخوانی API در دسترس نبودن باعث از کار افتادن در شروع میشود. از @available (Swift) یا compileSdkVersion + minSdkVersion (Android) برای تعیین صریح حداقل نسخه استفاده کنید.
در بیلد Debug، منابع اغلب بدون بررسی پیکربندی از دایرکتوریهای منبع بارگذاری میشوند. در Release، Gradle و Xcode فیلتر کردن منابع را اعمال میکنند: اگر string یا drawable در بومیسازی هدف یافت نشود، برنامه یا از کار میافتد یا placeholder نمایش میدهد. این به ویژه برای Android حیاتی است: عدم ترجمه در values-XX منجر به ClassCastException در هنگام تجزیه XML میشود. قبل از بیلد Release همه بومیسازیها را با lint و xcodebuild -showBuildSettings بررسی کنید. برای تشخیص چنین مشکلاتی از TestFlight و Internal Testing track قبل از انتشار عمومی استفاده کنید — آنها روی دستگاههای واقعی با تنظیمات زبانی مختلف اجرا میشوند.
سوالات متداول
از نظر فنی بله، اگر یک بیلد Release Ad Hoc با نمادهای فعال روی دستگاه نصب کنید. اما در عمل این کار ناخوشایند است: کد بهینهسازی شده دستورالعملها را جابجا میکند، نقاط توقف جابجا میشوند و متغیرهای محلی ممکن است توسط کامپایلر حذف شوند.
شبیهساز 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 در Android و App Thinning در iOS استفاده کنید. منابع استفاده نشده را حذف کنید (shrinkResources)، PNG را با WebP جایگزین کنید، وابستگیها را از نظر کتابخانههای تکراری بررسی کنید و ProGuard را برای حذف تهاجمی کد مرده پیکربندی کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید