انتشار اپلیکیشن
پس از توسعه اپ، نوبت انتشار است. در این فصل با مراحل کامل publish به Play Store و App Store آشنا میشویم.
۱۳.۱ مقدمه
پس از توسعه اپ، نوبت انتشار است. در این فصل با مراحل کامل publish به Play Store و App Store آشنا میشویم.
۱۳.۲ آمادهسازی برای Production
۱. App Icon و Splash Screen
flutter pub add --dev flutter_launcher_icons flutter_native_splash
# pubspec.yaml
flutter_launcher_icons:
android: true
ios: true
image_path: "assets/icon/icon.png"
min_sdk_android: 21
remove_alpha_ios: true
flutter_native_splash:
color: "#02569B"
image: assets/splash/splash.png
android_12:
image: assets/splash/splash_android12.png
color: "#02569B"
flutter pub run flutter_launcher_icons
flutter pub run flutter_native_splash:create
۲. App Name و Bundle ID
flutter pub add --dev rename
flutter pub run rename setBundleId --targets ios,android --value "com.icsd.shop"
flutter pub run rename setAppName --targets ios,android --value "فروشگاه"
۳. Version
# pubspec.yaml
# version: major.minor.patch+buildNumber
version: 1.0.0+1
۱۳.۳ Build برای Android
تولید Keystore
keytool -genkey -v -keystore ~/upload-keystore.jks
-keyalg RSA -keysize 2048 -validity 10000
-alias upload
پیکربندی Signing
# android/key.properties (نباید در Git!)
storePassword=YOUR_PASSWORD
keyPassword=YOUR_PASSWORD
keyAlias=upload
storeFile=/path/to/upload-keystore.jks
// android/app/build.gradle
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
signingConfigs {
release {
keyAlias keystoreProperties["keyAlias"]
keyPassword keystoreProperties["keyPassword"]
storeFile keystoreProperties["storeFile"] ? file(keystoreProperties["storeFile"]) : null
storePassword keystoreProperties["storePassword"]
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
shrinkResources true
}
}
}
Build APK یا AAB
# APK (برای تست یا direct distribution)
flutter build apk --release
# Split APK ها (سبکتر)
flutter build apk --split-per-abi --release
# نتیجه: 3 APK برای armeabi-v7a، arm64-v8a، x86_64
# AAB (پیشنهاد برای Play Store)
flutter build appbundle --release
# مسیر خروجی:
# build/app/outputs/flutter-apk/app-release.apk
# build/app/outputs/bundle/release/app-release.aab
۱۳.۴ انتشار در Google Play Store
گام ۱: ساخت حساب Developer
- هزینه یکبار: $25
- سایت:
play.google.com/console - نیاز به verification (مدارک، شماره)
گام ۲: ساخت Application
- Play Console → Create App
- اطلاعات اولیه: نام، زبان، نوع (App/Game)، رایگان/پولی
- قبول قوانین Google Play
گام ۳: Store Listing
- عنوان (تا ۳۰ کاراکتر)
- توضیح کوتاه (۸۰ کاراکتر)
- توضیح کامل (۴۰۰۰ کاراکتر) — مهم برای SEO
- Icon (512×512)
- Feature Graphic (1024×500)
- Screenshots: حداقل ۲ از تلفن، ۸ توصیه میشود
- دستهبندی
- Privacy Policy URL (اجباری)
- اطلاعات تماس
گام ۴: Content Rating
پرسشنامهای پاسخ میدهید و رده سنی تعیین میشود.
گام ۵: Pricing & Distribution
کشورها، رایگان/پولی، Family Program.
گام ۶: Upload AAB
- Production track → Create new release
- Upload .aab
- Release notes (در ۵۰۰ کاراکتر)
- Review → Start rollout
زمان review: ۲ ساعت تا چند روز. اگر اپلیکیشن جدید است معمولاً ۲-۳ روز.
Tracks مختلف
- Internal testing: تا ۱۰۰ نفر، فوری
- Closed testing: لیست خاص، تا ۱۰۰۰
- Open testing: هر کسی با opt-in
- Production: همه
۱۳.۵ Build برای iOS
پیشنیاز: Mac با Xcode + حساب Apple Developer ($99 سالانه).
# Build بدون signing (برای تست)
flutter build ios --release --no-codesign
# Build کامل
flutter build ipa
پیکربندی در Xcode
- باز کردن:
open ios/Runner.xcworkspace - Runner → Signing & Capabilities
- Team را انتخاب کنید (Apple Developer Account)
- Bundle Identifier:
com.icsd.shop - Capabilities: Push Notifications، Background Modes (در صورت نیاز)
Archive و Upload
- Product → Destination → Any iOS Device
- Product → Archive
- Window → Organizer
- Distribute App → App Store Connect → Upload
۱۳.۶ انتشار در App Store
گام ۱: App Store Connect
appstoreconnect.apple.com
- My Apps → “+” → New App
- Bundle ID را انتخاب کنید
- اطلاعات اولیه
گام ۲: Information
- Privacy Policy URL
- Category
- Content Rights
- Age Rating
گام ۳: Pricing & Availability
گام ۴: App Privacy (Privacy Manifest)
باید توضیح دهید چه دادههایی جمعآوری میکنید (مهم!).
گام ۵: Version Information
- What’s new (release notes)
- Screenshots: 6.5″ iPhone، 5.5″ iPhone، iPad (در صورت پشتیبانی)
- Description
- Keywords (تا ۱۰۰ کاراکتر — مهم برای ASO)
- Support URL
- Promotional Text
گام ۶: Build
Build که از Xcode upload شده، اینجا قابل انتخاب است.
گام ۷: Submit for Review
زمان review: ۲۴-۴۸ ساعت معمولاً. اولین submit ممکن است طولانیتر باشد.
- Crash در testing
- عدم تطبیق با Apple Human Interface Guidelines
- Privacy Policy ناکامل
- عدم اشاره به subscription
- استفاده از APIهای ممنوع
۱۳.۷ CI/CD با CodeMagic
CodeMagic بهخصوص برای Flutter ساخته شده.
# codemagic.yaml
workflows:
android-workflow:
name: Android Release
instance_type: mac_mini_m1
max_build_duration: 60
environment:
android_signing:
- keystore_reference
groups:
- google_play
flutter: stable
triggering:
events:
- push
branch_patterns:
- pattern: main
include: true
scripts:
- name: Get dependencies
script: flutter pub get
- name: Run tests
script: flutter test
- name: Build AAB
script: flutter build appbundle --release
artifacts:
- build/**/outputs/**/*.aab
publishing:
google_play:
credentials: $GCLOUD_SERVICE_ACCOUNT_CREDENTIALS
track: internal
submit_as_draft: false
ios-workflow:
name: iOS Release
instance_type: mac_mini_m1
environment:
ios_signing:
distribution_type: app_store
bundle_identifier: com.icsd.shop
groups:
- app_store_connect
flutter: stable
xcode: latest
scripts:
- name: Get dependencies
script: flutter pub get
- name: Build IPA
script: |
flutter build ipa --release
--export-options-plist=/Users/builder/export_options.plist
artifacts:
- build/ios/ipa/*.ipa
publishing:
app_store_connect:
api_key: $APP_STORE_CONNECT_PRIVATE_KEY
key_id: $APP_STORE_CONNECT_KEY_IDENTIFIER
issuer_id: $APP_STORE_CONNECT_ISSUER_ID
submit_to_testflight: true
۱۳.۸ Fastlane
ابزار اتوماسیون قدیمیتر ولی قدرتمند.
# Android
cd android
fastlane init
# iOS
cd ios
fastlane init
# android/fastlane/Fastfile
default_platform(:android)
platform :android do
desc "Deploy to Play Store internal testing"
lane :internal do
sh "cd ../.. && flutter build appbundle --release"
upload_to_play_store(
track: "internal",
aab: "../build/app/outputs/bundle/release/app-release.aab",
)
end
desc "Deploy to production"
lane :production do
sh "cd ../.. && flutter build appbundle --release"
upload_to_play_store(
track: "production",
aab: "../build/app/outputs/bundle/release/app-release.aab",
)
end
end
# اجرا:
# fastlane internal
# fastlane production
۱۳.۹ فروشگاههای ایرانی
به دلیل محدودیتهای Google Play در ایران، فروشگاههای ایرانی نیز مهم هستند:
- کافه بازار: بزرگترین فروشگاه.
cafebazaar.ir/dev - مایکت:
myket.ir/develop - سیب اپ (iOS):
sibapp.com - سیب چه:
sibche.com - اناردونی:
anardoni.com
برای انتشار در همه اینها، باید مدارک شرکت یا ID Card ارائه دهید.
۱۳.۱۰ بعد از انتشار
Crash Reporting با Firebase Crashlytics
flutter pub add firebase_crashlytics
import "package:firebase_crashlytics/firebase_crashlytics.dart";
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
runApp(const MyApp());
}
// ثبت خطای دستی
try {
// ...
} catch (e, stack) {
FirebaseCrashlytics.instance.recordError(e, stack);
}
Analytics
flutter pub add firebase_analytics
final analytics = FirebaseAnalytics.instance;
await analytics.logEvent(
name: "purchase",
parameters: {
"value": 50000,
"currency": "IRR",
"items": ["item1", "item2"],
},
);
// log screen
await analytics.logScreenView(screenName: "ProductDetailPage");
// User properties
await analytics.setUserProperty(name: "subscription", value: "premium");
۱۳.۱۱ بهترین تجربیات
- Internal testing اول. سپس closed/open، بعد production.
- Privacy Policy ضروری. در یک URL در دسترس.
- Screenshots حرفهای. تأثیر زیاد روی conversion.
- Description SEO شده.
- Crashlytics از روز اول.
- Analytics برای understanding users.
- OTA updates با Shorebird. بدون store review.
- A/B testing با Firebase.
- پاسخ به نظرات.
- Update منظم. Google rank میدهد.
۱۳.۱۲ خلاصه فصل
- آمادهسازی: icon، splash، version
- Build APK/AAB و IPA
- Signing با Keystore (Android)
- Play Store: tracks مختلف
- App Store: review process
- CI/CD با CodeMagic و Fastlane
- فروشگاههای ایرانی
- Crashlytics و Analytics