~/icsd.ir — bash
SYSTEM_ONLINE

انتشار اپلیکیشن

پس از توسعه اپ، نوبت انتشار است. در این فصل با مراحل کامل 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

  1. Play Console → Create App
  2. اطلاعات اولیه: نام، زبان، نوع (App/Game)، رایگان/پولی
  3. قبول قوانین Google Play

گام ۳: Store Listing

  • عنوان (تا ۳۰ کاراکتر)
  • توضیح کوتاه (۸۰ کاراکتر)
  • توضیح کامل (۴۰۰۰ کاراکتر) — مهم برای SEO
  • Icon (512×512)
  • Feature Graphic (1024×500)
  • Screenshots: حداقل ۲ از تلفن، ۸ توصیه می‌شود
  • دسته‌بندی
  • Privacy Policy URL (اجباری)
  • اطلاعات تماس

گام ۴: Content Rating

پرسشنامه‌ای پاسخ می‌دهید و رده سنی تعیین می‌شود.

گام ۵: Pricing & Distribution

کشورها، رایگان/پولی، Family Program.

گام ۶: Upload AAB

  1. Production track → Create new release
  2. Upload .aab
  3. Release notes (در ۵۰۰ کاراکتر)
  4. 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

  1. باز کردن: open ios/Runner.xcworkspace
  2. Runner → Signing & Capabilities
  3. Team را انتخاب کنید (Apple Developer Account)
  4. Bundle Identifier: com.icsd.shop
  5. Capabilities: Push Notifications، Background Modes (در صورت نیاز)

Archive و Upload

  1. Product → Destination → Any iOS Device
  2. Product → Archive
  3. Window → Organizer
  4. Distribute App → App Store Connect → Upload

۱۳.۶ انتشار در App Store

گام ۱: App Store Connect

appstoreconnect.apple.com

  1. My Apps → “+” → New App
  2. Bundle ID را انتخاب کنید
  3. اطلاعات اولیه

گام ۲: 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");
    

۱۳.۱۱ بهترین تجربیات

  1. Internal testing اول. سپس closed/open، بعد production.
  2. Privacy Policy ضروری. در یک URL در دسترس.
  3. Screenshots حرفه‌ای. تأثیر زیاد روی conversion.
  4. Description SEO شده.
  5. Crashlytics از روز اول.
  6. Analytics برای understanding users.
  7. OTA updates با Shorebird. بدون store review.
  8. A/B testing با Firebase.
  9. پاسخ به نظرات.
  10. 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
در فصل بعد: معماری Clean Architecture برای پروژه‌های بزرگ.

نمایش سایت

رنگ سایت
حالت نمایش
اندازهٔ متن
خوانایی

این تنظیمات فقط روی مرورگر شما ذخیره می‌شود.