Skip to content

📱 Uygulama Yayınlama Kapsamlı Rehberi (App Publishing Comprehensive Guide)

Mobil uygulama yayınlama sürecinin A'dan Z'ye pratik referans rehberi. A comprehensive reference for publishing mobile apps — from store setup to release management.

Bu rehber kimler için?

İlk kez uygulama yayınlayanlar: Adım adım hesap açma, build, imzalama, store listing

Deneyimli geliştiriciler: ASO, monetization, CI/CD, release yönetimi referansı

Takım liderleri: Politika uyumu, inceleme süreçleri, staged rollout stratejileri

1. Android — Google Play Store Yayınlama

1.1 Google Play Console Hesap Açma (Account Setup)

Google Play'de uygulama yayınlamak için bir geliştirici hesabı gereklidir.

Gereksinimler:
├── Google hesabı (Gmail)
├── Tek seferlik kayıt ücreti: $25 USD (one-time fee)
├── Kimlik doğrulama (identity verification)
├── Ödeme profili (payment profile — gelir almak için)
└── D-U-N-S numarası (organizasyon hesapları için / for organization accounts)

Hesap Türleri (Account Types)

ÖzellikBireysel (Personal)Organizasyon (Organization)
Kayıt ücreti$25$25
Kimlik doğrulamaKişisel IDD-U-N-S + Kişisel ID
Geliştirici adıKişisel isimŞirket adı
İletişim bilgisiKişiselKurumsal
Uygun kullanımBireysel projelerŞirket uygulamaları
bash
# Hesap açma adımları (account creation steps):
# 1. https://play.google.com/console adresine git
# 2. Google hesabı ile giriş yap (sign in with Google)
# 3. Hesap türünü seç (choose account type)
# 4. Geliştirici bilgilerini doldur (fill developer info)
# 5. $25 ödeme yap (pay registration fee)
# 6. Kimlik doğrulamasını tamamla (complete identity verification)
# 7. Onay bekle — genellikle 2-7 gün (wait for approval — usually 2-7 days)

💡 İpucu: Organizasyon hesabı açarken D-U-N-S numarası zorunludur. Bu numarayı Dun & Bradstreet üzerinden ücretsiz alabilirsiniz (ücretsiz başvuru ~30 gün sürer).

1.2 APK vs AAB — Build Formatları (Build Formats)

2021'den itibaren Google Play, AAB (Android App Bundle) formatını zorunlu kıldı.

ÖzellikAPKAAB (App Bundle)
Tam adıAndroid PackageAndroid App Bundle
Uzantı.apk.aab
Google Play❌ Artık kabul edilmiyor (no longer accepted)✅ Zorunlu (required)
Boyut optimizasyonuYok — tüm kaynaklar dahil✅ Cihaza özel APK üretilir
Dosya boyutuDaha büyük (larger)%15-20 daha küçük (smaller)
Doğrudan kurulum✅ Evet (sideload)❌ Hayır — Play Store gerekli
İmzalama (Signing)Geliştirici imzalarPlay App Signing zorunlu
Maksimum boyut~100 MB (+ expansion files)150 MB (+ asset packs)
AAB Çalışma Prensibi (How AAB Works):
┌─────────────┐    ┌──────────────────┐    ┌─────────────────┐
│  Developer   │───▶│  Google Play     │───▶│  User Device    │
│  .aab upload │    │  Split APKs      │    │  Optimized APK  │
│              │    │  oluşturur       │    │  indirir        │
└─────────────┘    └──────────────────┘    └─────────────────┘
                   Cihaza özel:
                   - CPU mimarisi (arm64, x86)
                   - Ekran yoğunluğu (density)
                   - Dil kaynakları (language)

⚠️ Önemli: APK formatı yalnızca dahili dağıtım (internal distribution), Firebase App Distribution veya sideload için kullanılabilir. Play Store'a yükleme için AAB zorunludur.

1.3 Keystore Oluşturma ve İmzalama (Keystore & Signing)

Android uygulamaları dijital olarak imzalanmalıdır (must be digitally signed).

Keystore Oluşturma (Creating a Keystore)

bash
# Yeni keystore oluştur (create new keystore)
keytool -genkey -v \
  -keystore my-release-key.jks \
  -keyalg RSA \
  -keysize 2048 \
  -validity 10000 \
  -alias my-key-alias

# Bilgi gir (enter information):
# - Keystore şifresi (password)
# - Ad Soyad (first and last name)
# - Organizasyon birimi (organizational unit)
# - Organizasyon adı (organization name)
# - Şehir (city)
# - İl (state)
# - Ülke kodu (country code): TR

🚨 KRİTİK: Keystore dosyasını ve şifrelerini güvenli bir yerde saklayın. Kaybederseniz uygulamanızı güncelleyemezsiniz! (If you lose the keystore, you cannot update your app!)

Gradle İmzalama Yapılandırması (Signing Configuration)

groovy
// android/app/build.gradle

android {
    signingConfigs {
        release {
            storeFile file('../my-release-key.jks')
            storePassword System.getenv("KEYSTORE_PASSWORD") ?: ''
            keyAlias 'my-key-alias'
            keyPassword System.getenv("KEY_PASSWORD") ?: ''
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled true          // Kod küçültme (code shrinking)
            shrinkResources true        // Kaynak küçültme (resource shrinking)
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                         'proguard-rules.pro'
        }
    }
}

Play App Signing (Google Yönetimli İmzalama)

İmzalama Akışı (Signing Flow):
┌──────────────┐    ┌─────────────────┐    ┌──────────────┐
│  Upload Key  │───▶│  Play App       │───▶│  App Signing │
│  (Sizin)     │    │  Signing        │    │  Key         │
│  .aab imzalar│    │  Re-sign yapar  │    │  (Google)    │
└──────────────┘    └─────────────────┘    └──────────────┘
Geliştirici                Google                  Kullanıcı
yükler                     yönetir                 indirir
bash
# Play App Signing anahtarını dışa aktar (export for local testing)
# Play Console > Setup > App signing bölümünden SHA-256 parmak izini alın
# Console > Setup > App signing — get SHA-256 fingerprint

# Upload key kaybedilirse (if upload key is lost):
# Play Console > Setup > App signing > Request upload key reset
# Yeni bir upload key oluşturup Google'a göndermeniz gerekir

1.4 Build — Release APK/AAB Oluşturma

Native Android (Gradle)

bash
# Release AAB oluştur (build release AAB)
cd android/
./gradlew bundleRelease

# Çıktı konumu (output location):
# app/build/outputs/bundle/release/app-release.aab

# Release APK oluştur — dahili dağıtım için (for internal distribution)
./gradlew assembleRelease

# Çıktı konumu:
# app/build/outputs/apk/release/app-release.apk

Flutter

bash
# Flutter AAB oluştur (build Flutter AAB)
flutter build appbundle --release

# Çıktı: build/app/outputs/bundle/release/app-release.aab

# Flutter APK oluştur (for testing/sideload)
flutter build apk --release --split-per-abi

# Çıktı: build/app/outputs/flutter-apk/
#   app-armeabi-v7a-release.apk
#   app-arm64-v8a-release.apk
#   app-x86_64-release.apk

React Native

bash
# React Native AAB oluştur (build React Native AAB)
cd android/
./gradlew bundleRelease

# Çıktı: app/build/outputs/bundle/release/app-release.aab

# npx react-native ile (alternative)
npx react-native build-android --mode=release

Expo (EAS Build)

bash
# EAS CLI kur (install EAS CLI)
npm install -g eas-cli

# EAS'e giriş yap (login to EAS)
eas login

# eas.json yapılandır (configure eas.json)
eas build:configure

# Production AAB oluştur (build production AAB)
eas build --platform android --profile production

# Preview APK oluştur — test için (build preview APK for testing)
eas build --platform android --profile preview
json
// eas.json
{
  "build": {
    "preview": {
      "android": {
        "buildType": "apk"
      }
    },
    "production": {
      "android": {
        "buildType": "app-bundle"
      }
    }
  }
}

1.5 Play Console — Uygulama Oluşturma ve Store Listing

Uygulama Oluşturma Adımları (App Creation Steps)

Play Console Dashboard:
├── 1. Uygulama oluştur (Create app)
│   ├── Uygulama adı (App name)
│   ├── Varsayılan dil (Default language)
│   ├── Uygulama türü: App / Game
│   └── Ücretsiz / Ücretli (Free / Paid)

├── 2. Dashboard checklist'i tamamla (Complete dashboard checklist)
│   ├── Gizlilik politikası (Privacy policy URL)
│   ├── Uygulama erişimi (App access — login gerekli mi?)
│   ├── Reklam beyanı (Ads declaration)
│   ├── İçerik derecelendirme (Content rating questionnaire)
│   ├── Hedef kitle (Target audience — çocuklar dahil mi?)
│   ├── Haber uygulaması beyanı (News app declaration)
│   ├── COVID-19 beyanı (if applicable)
│   └── Data safety formu (Data safety form)

├── 3. Store listing (Mağaza listesi)
│   ├── Kısa açıklama (Short description — 80 karakter max)
│   ├── Tam açıklama (Full description — 4000 karakter max)
│   ├── Uygulama ikonu (App icon — 512x512 PNG)
│   ├── Öne çıkan görsel (Feature graphic — 1024x500)
│   ├── Ekran görüntüleri (Screenshots)
│   └── Video (YouTube linki — opsiyonel)

└── 4. Release oluştur (Create release)
    ├── Test track veya Production seç
    ├── AAB yükle (Upload AAB)
    ├── Release notes yaz
    └── İncelemeye gönder (Submit for review)

Ekran Görüntüsü Gereksinimleri (Screenshot Requirements)

TürBoyutAdet
Telefon (Phone)16:9 veya 9:16, min 320px, max 3840pxMin 2, Max 8
7" Tablet16:9 veya 9:16Opsiyonel, Max 8
10" Tablet16:9 veya 9:16Opsiyonel, Max 8
Chromebook16:9Opsiyonel, Max 8
Wear OS1:1Opsiyonel, Max 8
TV16:9, 1920x1080Opsiyonel, Max 8

1.6 İnceleme Süreci (Review Process)

İnceleme Akışı (Review Flow):
┌────────┐    ┌───────────┐    ┌───────────┐    ┌──────────┐
│ Submit │───▶│ In Review │───▶│ Approved  │───▶│ Live     │
│        │    │ (1-3 gün) │    │           │    │          │
└────────┘    └─────┬─────┘    └───────────┘    └──────────┘


              ┌───────────┐
              │ Rejected  │──▶ Düzelt ve tekrar gönder
              │           │    (Fix and resubmit)
              └───────────┘
DurumAçıklama
DraftTaslak — henüz gönderilmedi (not submitted yet)
In Reviewİnceleniyor — Google ekibi kontrol ediyor
ApprovedOnaylandı — yayınlanmaya hazır
RejectedReddedildi — sorunları düzelt ve tekrar gönder
SuspendedAskıya alındı — ciddi politika ihlali

💡 Süre: İlk uygulama incelemeleri genellikle 1-3 iş günü sürer. Güncellemeler daha hızlı olabilir (birkaç saat). Yeni geliştirici hesapları için ilk inceleme daha uzun sürebilir (up to 7 days for new accounts).

1.7 Test Track'ler (Testing Tracks)

Google Play, uygulamanızı aşamalı olarak test etmenizi sağlar.

TrackAmaçTest kullanıcı sayısı
Internal testingHızlı dahili test (quick internal test)Max 100
Closed testingBelirli kullanıcılarla beta (invite-only beta)Sınırsız (unlimited)
Open testingHerkese açık beta (public beta)Sınırsız
ProductionCanlı yayın (live release)Tüm kullanıcılar
bash
# Internal test — inceleme gerektirmez (no review needed)
# Yükleme sonrası dakikalar içinde kullanılabilir
# Ideal: QA ekibi, dahili test

# Closed testing — sınırlı inceleme
# E-posta listesi veya Google Groups ile davet
# Ideal: Beta kullanıcıları, erken erişim

# Open testing — tam inceleme gerektirir
# Play Store'da "Beta'ya katıl" butonu görünür
# Ideal: Geniş çaplı test, geri bildirim toplama
Test Akışı Önerisi (Recommended Test Flow):
Internal ──▶ Closed Beta ──▶ Open Beta ──▶ Production
 (Ekip)      (Seçili         (Herkes)      (Canlı)
              kullanıcılar)

1.8 ProGuard / R8 — Kod Optimizasyonu

R8, Android'in varsayılan kod küçültme aracıdır (default code shrinker). ProGuard'ın yerini almıştır.

groovy
// android/app/build.gradle
android {
    buildTypes {
        release {
            minifyEnabled true          // Kod küçültme (shrink code)
            shrinkResources true        // Kullanılmayan kaynakları sil (remove unused resources)
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                         'proguard-rules.pro'
        }
    }
}

Yaygın ProGuard Kuralları (Common ProGuard Rules)

text
# proguard-rules.pro

# Retrofit / API modelleri (keep API models)
-keep class com.example.app.model.** { *; }

# Gson serialization
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.google.gson.** { *; }

# Firebase
-keep class com.google.firebase.** { *; }

# React Native — gerekli kurallar
-keep class com.facebook.react.** { *; }
-keep class com.facebook.hermes.** { *; }

# Flutter — genellikle ek kural gerekmez
# Flutter usually doesn't need extra rules

# Debug bilgilerini kaldır (remove debug info)
-assumenosideeffects class android.util.Log {
    public static int v(...);
    public static int d(...);
    public static int i(...);
}

# Crash raporlama için satır numaralarını koru (keep line numbers for crash reports)
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
R8 İşleviAçıklama
Code shrinkingKullanılmayan kodu siler (removes unused code)
ObfuscationSınıf/metot adlarını kısaltır (shortens class/method names)
OptimizationKodu optimize eder (optimizes bytecode)
Resource shrinkingKullanılmayan kaynakları siler (removes unused resources)

⚠️ Dikkat: R8 bazen gerekli kodları silebilir. Release build'i her zaman test edin! Özellikle reflection kullanan kütüphaneler (Gson, Retrofit) için -keep kuralları eklemeyi unutmayın.

1.9 Google Play Politikaları ve Yaygın Red Nedenleri

İçerik Politikaları (Content Policies)

PolitikaAçıklamaRed Nedeni Örneği
Kısıtlı içerikŞiddet, nefret söylemi, kumar yasakYaş doğrulama olmadan yetişkin içerik
Fikri mülkiyetTelif hakkı ihlali yasakBaşka markanın logosunu/adını kullanmak
Yanıltıcı davranışAldatıcı uygulamalar yasakSahte işlevsellik iddiası
Cihaz ve ağ kötüye kullanımıMalware, arka plan kötüye kullanımGereksiz background servis

Gizlilik Politikaları (Privacy Policies)

Zorunlu Gizlilik Gereksinimleri:
├── Gizlilik politikası URL'si (Privacy policy URL — zorunlu)
├── Data Safety formu (Data Safety form — zorunlu)
│   ├── Hangi veriler toplanıyor? (What data is collected?)
│   ├── Veriler paylaşılıyor mu? (Is data shared?)
│   ├── Veriler şifreleniyor mu? (Is data encrypted?)
│   └── Kullanıcı veri silme talebinde bulunabilir mi? (Can users request deletion?)
├── COPPA uyumu — çocuk uygulamaları (children's apps compliance)
└── GDPR uyumu — AB kullanıcıları (EU user compliance)

İzin Politikaları (Permission Policies)

Yaygın Red Nedenleri — İzinler:
├── ❌ Gereksiz izin isteme (requesting unnecessary permissions)
│   └── Örnek: Hesap makinesi uygulaması kamera izni istiyor
├── ❌ Arka plan konum izni gerekçesiz (background location without justification)
│   └── Ek form doldurulması gerekir (additional form required)
├── ❌ SMS/Arama izni gereksiz kullanımı (unnecessary SMS/Call log access)
│   └── Sadece varsayılan SMS/telefon uygulamaları kullanabilir
├── ❌ QUERY_ALL_PACKAGES gereksiz kullanımı
│   └── Ek form gerekli (additional declaration form required)
└── ❌ Accessibility API kötüye kullanımı
    └── Yalnızca engelli kullanıcılara yönelik uygulamalar kullanabilir

Reklam Politikaları (Ad Policies)

KuralAçıklama
Reklam beyanıUygulama reklam içeriyorsa beyan zorunlu (ad declaration required)
Çocuk uygulamalarıÇocuklara yönelik uygulamalarda kişiselleştirilmiş reklam yasak
Aldatıcı reklamlarKapatması zor, tam ekran kapatan reklamlar yasak
Reklam IDAdID kullanımı beyan edilmeli

Ödeme Politikaları (Payment Policies)

DurumZorunlu Yöntem
Dijital içerik / özellik satışıGoogle Play Billing zorunlu (mandatory)
Fiziksel ürün satışıHarici ödeme kullanılabilir (external payment OK)
Abonelik (Subscription)Google Play Billing zorunlu
Bağış (Donation)Harici ödeme kullanılabilir

Metadata Politikaları (Metadata Policies)

Yaygın Red Nedenleri — Metadata:
├── ❌ Yanıltıcı uygulama adı (misleading app name)
├── ❌ Anahtar kelime spam — açıklamada aşırı kelime tekrarı (keyword stuffing)
├── ❌ Sahte ekran görüntüleri (fake screenshots)
├── ❌ Başka uygulamayı taklit eden ikon (copycat icon)
├── ❌ Yanlış kategori seçimi (wrong category selection)
└── ❌ Derecelendirme sorusu yanlış yanıtlama (incorrect content rating)
KaynakLink
Play Consolehttps://play.google.com/console
Developer Policy Centerhttps://play.google.com/about/developer-content-policy
Data Safetyhttps://support.google.com/googleplay/android-developer/answer/10787469
Launch Checklisthttps://developer.android.com/distribute/best-practices/launch/launch-checklist
Play App Signinghttps://developer.android.com/studio/publish/app-signing
Core Quality Guidelineshttps://developer.android.com/quality

2. iOS — App Store Yayınlama

2.1 Apple Developer Program (Geliştirici Programı)

Apple Developer Program:
├── Bireysel (Individual): $99/yıl ($99/year)
├── Organizasyon (Organization): $99/yıl + D-U-N-S gerekli
├── Enterprise: $299/yıl — sadece dahili dağıtım (internal distribution only)
└── Ücretsiz (Free tier): Geliştirme ve cihazda test (development & device testing)
    └── App Store'a yükleme yapılamaz (cannot publish to App Store)
ÖzellikÜcretsiz$99/yıl Bireysel$99/yıl Organizasyon
Xcode + Simulator
Cihazda test (on-device testing)
App Store yayınlama
TestFlight
Takım yönetimi (team management)
Gelişmiş yetenekler (Push, IAP vb.)
bash
# Kayıt adımları (enrollment steps):
# 1. https://developer.apple.com/programs adresine git
# 2. Apple ID ile giriş yap (sign in with Apple ID)
# 3. Hesap türünü seç (choose account type)
# 4. Bilgileri doldur (fill in information)
# 5. $99 ödeme yap (pay annual fee)
# 6. 48 saat içinde onay (approval within 48 hours)
# Not: Organizasyon hesapları için D-U-N-S numarası gereklidir

2.2 Xcode Build, Archive ve Organizer

Build Ayarları (Build Settings)

Xcode Build Süreci (Build Process):
┌──────────┐    ┌──────────┐    ┌──────────┐    ┌───────────┐
│  Clean   │───▶│  Build   │───▶│ Archive  │───▶│ Distribute│
│  Build   │    │  Release │    │          │    │ to App    │
│          │    │          │    │          │    │ Store     │
└──────────┘    └──────────┘    └──────────┘    └───────────┘
bash
# Xcode komut satırından build (build from command line)

# Temiz build (clean build)
xcodebuild clean -workspace MyApp.xcworkspace -scheme MyApp

# Archive oluştur (create archive)
xcodebuild archive \
  -workspace MyApp.xcworkspace \
  -scheme MyApp \
  -archivePath ./build/MyApp.xcarchive \
  -configuration Release

# Archive'ı dışa aktar — App Store dağıtımı (export for App Store)
xcodebuild -exportArchive \
  -archivePath ./build/MyApp.xcarchive \
  -exportPath ./build/export \
  -exportOptionsPlist ExportOptions.plist

ExportOptions.plist

xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>app-store</string>
    <key>teamID</key>
    <string>YOUR_TEAM_ID</string>
    <key>uploadBitcode</key>
    <false/>
    <key>uploadSymbols</key>
    <true/>
</dict>
</plist>

Organizer ile Yükleme (Upload with Organizer)

Xcode Organizer Adımları:
1. Xcode > Product > Archive
2. Organizer otomatik açılır (Organizer opens automatically)
3. "Distribute App" butonuna tıkla
4. "App Store Connect" seç
5. "Upload" seç (veya "Export" — Transporter ile yüklemek için)
6. Sertifika ve profil seç (select certificate & profile)
7. Yükleme tamamlanır (upload completes)
8. App Store Connect'te uygulamayı gör (view in App Store Connect)

2.3 Sertifika Yönetimi (Certificate Management)

Sertifika Türleri (Certificate Types)

SertifikaKullanımGeçerlilik
DevelopmentGeliştirme ve cihaz testi1 yıl (1 year)
Distribution (App Store)App Store dağıtımı1 yıl
Distribution (Ad Hoc)Sınırlı cihaz dağıtımı (limited device distribution)1 yıl
Apple Push NotificationPush bildirim (push notifications)1 yıl

Provisioning Profile Türleri

Provisioning Profile Yapısı (Structure):
┌─────────────────────────────┐
│    Provisioning Profile     │
├─────────────────────────────┤
│  App ID (Bundle Identifier) │
│  Sertifika (Certificate)    │
│  Cihaz listesi (Devices)*   │  * Distribution profile'da yok
│  Yetenekler (Capabilities)  │
│  Son kullanma (Expiration)  │
└─────────────────────────────┘
Profile TürüAmaçCihaz Kısıtı
DevelopmentGeliştirme testiMax 100 cihaz
Ad HocBeta dağıtım (beta distribution)Max 100 cihaz
App StoreApp Store yayınlamaCihaz kısıtı yok (no device limit)
EnterpriseDahili dağıtım (internal — $299 plan)Sınırsız (unlimited)
bash
# Otomatik sertifika yönetimi (automatic signing — önerilen / recommended)
# Xcode > Target > Signing & Capabilities > "Automatically manage signing" ✅

# Manuel sertifika yönetimi (manual signing)
# 1. Apple Developer Portal'da sertifika oluştur
# 2. Provisioning Profile oluştur
# 3. İndir ve Xcode'a yükle
# 4. Build Settings > Code Signing Identity ayarla
# 5. Build Settings > Provisioning Profile ayarla

# Fastlane ile otomatik yönetim (recommended for CI/CD)
# fastlane match — sertifikaları Git repo'da saklar
fastlane match appstore    # App Store sertifikası
fastlane match development # Development sertifikası
fastlane match adhoc       # Ad Hoc sertifikası

2.4 App Store Connect — Metadata ve Ekran Görüntüleri

Zorunlu Metadata (Required Metadata)

App Store Connect Bilgileri:
├── Uygulama adı (App name — 30 karakter max)
├── Subtitle (30 karakter max)
├── Kategori (Category — primary + secondary)
├── Açıklama (Description — 4000 karakter max)
├── Promotional text (170 karakter — her zaman güncellenebilir)
├── Anahtar kelimeler (Keywords — 100 karakter, virgülle ayrılmış)
├── Destek URL (Support URL — zorunlu)
├── Pazarlama URL (Marketing URL — opsiyonel)
├── Gizlilik politikası URL (Privacy policy URL — zorunlu)
├── Yaş derecelendirmesi (Age rating — zorunlu)
├── Telif hakkı (Copyright — zorunlu)
└── İletişim bilgisi (Contact info — zorunlu)

Ekran Görüntüsü Gereksinimleri (Screenshot Requirements)

CihazBoyut (Piksel)Adet
iPhone 6.9" (15 Pro Max)1320 x 28681-10
iPhone 6.7" (14 Pro Max)1290 x 27961-10
iPhone 6.5" (11 Pro Max)1242 x 26881-10
iPhone 5.5" (8 Plus)1242 x 22081-10
iPad Pro 12.9" (6. nesil)2048 x 27321-10
iPad Pro 12.9" (2. nesil)2048 x 27321-10
Apple WatchCihaza göre değişir1-10
Apple TV1920 x 1080 veya 3840 x 21601-10

💡 İpucu: iPhone 6.7" ekran görüntüleri yüklerseniz, 6.5" için de otomatik kullanılabilir (aynı oran). iPad 12.9" (6. nesil) yüklerseniz 2. nesil için de kullanılır.

2.5 TestFlight — Beta Test

TestFlight, Apple'ın resmi beta test platformudur (official beta testing platform).

TestFlight Kullanıcı Türleri:
├── Internal Testers (Dahili test kullanıcıları)
│   ├── Max 100 kişi
│   ├── App Store Connect üyesi olmalı
│   ├── İnceleme gerektirmez (no review needed)
│   └── Build yüklendikten sonra hemen kullanılabilir

└── External Testers (Harici test kullanıcıları)
    ├── Max 10.000 kişi
    ├── E-posta ile davet veya herkese açık link
    ├── İlk build için beta incelemesi gerekir (beta review required)
    └── İnceleme genellikle 24-48 saat sürer
bash
# TestFlight süreci (TestFlight process):
# 1. Xcode'dan Archive ve Upload yap
# 2. App Store Connect'te build'i bekle (processing ~5-30 dakika)
# 3. Compliance bilgilerini doldur (export compliance)
# 4. Internal veya External grubu seç
# 5. Test notları ekle (what to test)
# 6. Gönder (submit)

# Test kullanıcıları TestFlight uygulamasını indirip uygulamayı test eder
# Testers download the TestFlight app and test the build
# Her build 90 gün geçerlidir (each build expires after 90 days)

2.6 İnceleme Süreci (App Review Process)

İnceleme Akışı (Review Flow):
┌──────────┐    ┌──────────────┐    ┌───────────┐    ┌──────────┐
│ Submit   │───▶│ Waiting for  │───▶│ In Review │───▶│ Approved │
│ for      │    │ Review       │    │ (Manuel   │    │          │
│ Review   │    │ (Kuyrukta)   │    │  kontrol) │    │          │
└──────────┘    └──────────────┘    └─────┬─────┘    └──────────┘


                                   ┌───────────┐
                                   │ Rejected  │
                                   │ (Red)     │
                                   └───────────┘
SüreDurum
İlk gönderim (first submission)1-7 gün (usually 24-48 hours)
Güncelleme (update)1-3 gün (often same day)
Expedited review (acil inceleme)Talep edilebilir — garanti yok
TestFlight beta review24-48 saat

💡 İpucu: Acil durumlarda (kritik bug fix, güvenlik açığı) Apple'dan hızlandırılmış inceleme talep edebilirsiniz: https://developer.apple.com/contact/app-store/?topic=expedite

2.7 EAS Build — Expo ile Xcode'suz Build

Expo kullanıyorsanız, Mac olmadan bile iOS build oluşturabilirsiniz.

bash
# EAS CLI kur (install EAS CLI)
npm install -g eas-cli

# Giriş yap (login)
eas login

# iOS build — App Store dağıtımı (App Store distribution)
eas build --platform ios --profile production

# iOS build — Simulator (test)
eas build --platform ios --profile development-simulator

# iOS build — dahili dağıtım (internal distribution via ad-hoc)
eas build --platform ios --profile preview
json
// eas.json — iOS yapılandırması (iOS configuration)
{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "ios": {
        "simulator": false
      }
    },
    "development-simulator": {
      "developmentClient": true,
      "distribution": "internal",
      "ios": {
        "simulator": true
      }
    },
    "preview": {
      "distribution": "internal",
      "ios": {
        "buildConfiguration": "Release"
      }
    },
    "production": {
      "ios": {
        "buildConfiguration": "Release"
      }
    }
  },
  "submit": {
    "production": {
      "ios": {
        "appleId": "your@email.com",
        "ascAppId": "123456789",
        "appleTeamId": "YOUR_TEAM_ID"
      }
    }
  }
}
bash
# EAS Submit — App Store Connect'e yükle (upload to App Store Connect)
eas submit --platform ios --profile production

# Build + Submit birlikte (build and submit together)
eas build --platform ios --profile production --auto-submit

2.8 macOS Olmadan iOS Build — Detaylı Rehber (iOS Build Without macOS)

macOS ve Xcode olmadan iOS uygulaması build etmenin yolları:

Yöntem 1: EAS Build (Expo — Önerilen)

En kolay yol. Expo projesi olması yeterli, cloud'da build alınır.

bash
# Gereksinimler:
# - Node.js
# - Expo projesi (npx create-expo-app veya mevcut RN + Expo)
# - Apple Developer hesabı ($99/yıl)
# - EAS CLI

# 1. EAS CLI kur
npm install -g eas-cli

# 2. Apple Developer hesabınla giriş yap
eas login

# 3. İlk kez: Apple credentials ayarla
# EAS otomatik olarak sertifika ve provisioning profile oluşturur
eas credentials  # Apple ID ve şifre sorar

# 4. iOS build al (cloud'da — macOS gerekmez!)
eas build --platform ios --profile production

# 5. Build durumunu takip et
eas build:list

# 6. Build bitince App Store'a gönder
eas submit --platform ios

# 7. Veya build + submit tek komutla
eas build --platform ios --profile production --auto-submit

EAS Build ücretsiz mi?

PlanAylık BuildHızFiyat
Free30 build/ayKuyrukta beklemeÜcretsiz
Production1000 build/ayÖncelikli$99/ay
EnterpriseSınırsızAdanmış sunucuÖzel fiyat

Free plan çoğu küçük-orta proje için yeterlidir.

Yöntem 2: Codemagic (Flutter + React Native)

yaml
# codemagic.yaml — iOS build yapılandırması
workflows:
  ios-release:
    name: iOS Release
    instance_type: mac_mini_m2  # Cloud macOS
    environment:
      ios_signing:
        distribution_type: app_store
        bundle_identifier: com.example.app
      vars:
        APP_STORE_CONNECT_KEY_IDENTIFIER: YOUR_KEY_ID
        APP_STORE_CONNECT_ISSUER_ID: YOUR_ISSUER_ID
    scripts:
      - name: Flutter build
        script: flutter build ipa --release
    artifacts:
      - build/ios/ipa/*.ipa
    publishing:
      app_store_connect:
        auth: integration
        submit_to_testflight: true

Codemagic ücretsiz mi?

PlanDakika/aymacOSFiyat
Free500 dkM1 Mac MiniÜcretsiz
Pay-as-you-goSınırsızM1/M2$0.038/dk
Team3000 dkM2 Pro$299/ay

Yöntem 3: GitHub Actions + macOS Runner

yaml
# .github/workflows/ios-build.yml
name: iOS Build
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: macos-latest  # GitHub'ın macOS runner'ı
    steps:
      - uses: actions/checkout@v4
      - uses: subosito/flutter-action@v2  # Flutter için
        with:
          flutter-version: '3.24.0'
      - run: flutter build ipa --release
      - uses: apple-actions/upload-testflight-build@v1
        with:
          app-path: build/ios/ipa/*.ipa
          issuer-id: $\{{ secrets.APPSTORE_ISSUER_ID }}
          api-key-id: $\{{ secrets.APPSTORE_API_KEY_ID }}
          api-private-key: $\{{ secrets.APPSTORE_API_PRIVATE_KEY }}

GitHub Actions macOS runner ücretsiz planda ayda 2000 dakika (public repo sınırsız).

Yöntem 4: Uzak Mac Kiralama (Remote Mac Rental)

ServisFiyatKullanım
MacStadium~$79/ayAdanmış Mac Mini
AWS EC2 Mac~$1.08/saatOn-demand Mac
MacinCloud~$20/ayPaylaşımlı Mac
Hetzner (Hackintosh)ToS ihlali, önerilmez

Tavsiye sırası: EAS Build (en kolay) → Codemagic (Flutter için) → GitHub Actions → Mac kiralama (son çare)

Karşılaştırma: macOS Olmadan iOS Build Yöntemleri

YöntemZorlukMaliyetFlutterReact NativeExpo
EAS BuildÇok kolayÜcretsiz (30/ay)
CodemagicKolayÜcretsiz (500dk/ay)
GitHub ActionsOrtaÜcretsiz (2000dk/ay)
Mac kiralamaZor$20-80/ay
Gerçek Mac satın al$700+ (Mac Mini)

2.9 App Store Politikaları ve Yaygın Red Nedenleri

Apple'ın inceleme süreci Google'dan daha katıdır. En yaygın red nedenleri:

4.2 Minimum Functionality (Minimum İşlevsellik)

Yaygın Red Senaryoları:
├── ❌ Sadece bir WebView olan uygulama (app is just a WebView / wrapper)
│   └── Çözüm: Native özellikler ekleyin (push notification, offline, kamera vb.)
├── ❌ Çok basit / yetersiz işlevsellik (too simple / not enough features)
│   └── Çözüm: Anlamlı kullanıcı deneyimi sunun
├── ❌ Beta / tamamlanmamış uygulama (beta / incomplete app)
│   └── Çözüm: TestFlight kullanın, tamamlanmadan gönderin
└── ❌ Web sitesinin birebir kopyası (duplicate of website)
    └── Çözüm: Mobil'e özel deneyim katın

2.1 Performance (Performans)

Yaygın Red Senaryoları:
├── ❌ Uygulama çöküyor / crash (app crashes)
├── ❌ Bozuk linkler veya placeholder içerik (broken links or placeholder content)
├── ❌ Yükleme süresi çok uzun (excessive loading time)
└── ❌ Eksik / hatalı özellikler (missing / buggy features)

5.1.1 Data Collection and Storage (Veri Toplama)

Gereksinimler (Requirements):
├── Gizlilik politikası zorunlu (Privacy policy required)
├── App Privacy Labels doğru doldurulmalı (nutrition labels must be accurate)
├── Kullanıcı izni olmadan veri toplanmaz (no data collection without consent)
├── App Tracking Transparency (ATT) — iOS 14.5+
│   └── IDFA erişimi için kullanıcı izni zorunlu
├── Minimum veri toplama ilkesi (collect only what's necessary)
└── Veri silme mekanizması sunulmalı (must offer data deletion)

3.1.1 In-App Purchase (Uygulama İçi Satın Alma)

Kurallar:
├── Dijital içerik/özellik → Apple IAP zorunlu (Apple IAP required)
│   └── Apple %30 komisyon alır (ilk yıl sonrası %15 — Small Business Program)
├── Fiziksel ürün/hizmet → Harici ödeme OK (external payment OK)
│   └── Uber, yemek siparişi, e-ticaret vb.
├── Abonelik → Apple IAP zorunlu (subscriptions must use Apple IAP)
├── ❌ Harici ödeme yönlendirmesi yasak (cannot direct to external payment)
│   └── 2024 güncellemesi: ABD'de external link entitlement mevcut
└── ❌ "Bu özellik web'de daha ucuz" yazılamaz

4.0 Design (Tasarım)

Yaygın Red Nedenleri:
├── ❌ Apple HIG'e uymayan tasarım (not following Human Interface Guidelines)
├── ❌ iPhone uygulaması iPad'de çalışmıyor (must support iPad if universal)
├── ❌ Landscape/Portrait desteği eksik
├── ❌ Notch/Dynamic Island uyumsuzluğu (incompatible with notch/Dynamic Island)
└── ❌ Erişilebilirlik eksikliği (accessibility issues)

Metadata Red Nedenleri (Metadata Rejections)

├── ❌ Ekran görüntüleri uygulamayı yansıtmıyor (screenshots don't match app)
├── ❌ "Beta", "test", "demo" ifadesi adda/açıklamada (beta/test/demo in name)
├── ❌ Yanlış kategori (wrong category)
├── ❌ Fiyatlandırma bilgisi açıklamada eksik (pricing info missing)
├── ❌ Diğer platformlara referans (referencing other platforms like Android)
└── ❌ Yanıltıcı uygulama adı veya ikon (misleading name or icon)
KaynakLink
App Store Connecthttps://appstoreconnect.apple.com
App Store Review Guidelineshttps://developer.apple.com/app-store/review/guidelines
Human Interface Guidelineshttps://developer.apple.com/design/human-interface-guidelines
App Privacyhttps://developer.apple.com/app-store/app-privacy-details
Developer Programhttps://developer.apple.com/programs
Expedited Reviewhttps://developer.apple.com/contact/app-store/?topic=expedite

3. App Store Optimization (ASO)

ASO, uygulamanızın mağaza içi görünürlüğünü artırma sürecidir (the process of improving app visibility in stores).

3.1 Uygulama Adı ve Subtitle Stratejisi (Name & Subtitle Strategy)

Adlandırma Best Practices:
├── Kısa ve akılda kalıcı (short and memorable)
├── Ana anahtar kelimeyi içersin (include primary keyword)
├── Rakiplerden farklılaşın (differentiate from competitors)
├── Kolay yazılabilir olsun (easy to spell)
└── Global pazarda anlaşılabilir (globally understandable)
PlatformAd LimitiSubtitle/Short Desc
App Store30 karakter30 karakter (subtitle)
Google Play30 karakter80 karakter (short description)
Örnek İsimlendirme (Example Naming):
✅ İyi: "FitTrack — Egzersiz Takibi" (ana kelime + açıklama)
✅ İyi: "Notion — Notes & Projects"
❌ Kötü: "En İyi Fitness Spor Sağlık Egzersiz Diyet Uygulaması" (keyword stuffing)
❌ Kötü: "MyApp v2.3.1" (versiyon numarası ad'da)

3.2 Anahtar Kelime Stratejisi (Keyword Strategy)

Anahtar Kelime Araştırması Araçları (Keyword Research Tools):
├── App Store — "Keywords" alanı (100 karakter, virgülle ayrılmış)
│   └── Boşluk bırakmayın, tekrar etmeyin, "app" yazmayın
├── Google Play — Açıklama metni + başlık (no keyword field)
│   └── İlk 2-3 cümlede anahtar kelimeleri kullanın
├── Araçlar (Tools):
│   ├── App Annie / data.ai
│   ├── Sensor Tower
│   ├── AppFollow
│   ├── MobileAction
│   └── AppTweak
└── Rakip analizi (competitor analysis)
    └── Rakiplerin hangi kelimelerde sıralandığını inceleyin
FaktörApp StoreGoogle Play
Uygulama adı✅ Çok önemli (very important)✅ Çok önemli
Subtitle✅ ÖnemliN/A
Keyword alanı✅ 100 karakterN/A
Açıklama❌ İndexlenmez (not indexed)✅ İndexlenir (indexed)
Geliştirici adıMinimal etki✅ İndexlenir
IAP adları✅ İndexlenirMinimal etki

3.3 İkon Tasarımı Best Practices

İkon Tasarım İlkeleri (Icon Design Principles):
├── Basit ve net (simple and clear) — karmaşık detaylardan kaçının
├── Tek bir odak noktası (single focal point)
├── Parlak, canlı renkler (bright, vivid colors)
├── Metin kullanmayın (avoid text in icon)
│   └── İstisna: Marka logosu tek harfse (e.g., Facebook "f")
├── Fotoğraf kullanmayın (avoid photos)
├── Kenarları temiz tutun (clean edges)
├── Rakiplerden farklılaşın (stand out from competitors)
└── Farklı boyutlarda test edin (test at various sizes — 29px to 1024px)
Platformİkon BoyutuFormatŞeffaflık
App Store1024x1024PNGYok (no transparency)
Google Play512x512PNG (32-bit)Kullanılabilir (allowed)

💡 İpucu: İkonunuzu küçük boyutlarda (29x29, 40x40) test edin — bildirim çubuğu ve ayarlarda bu boyutlarda görünür.

3.4 Ekran Görüntüsü Stratejisi (Screenshot Strategy)

Kritik Kurallar:
├── İlk 3 ekran görüntüsü EN önemli (first 3 screenshots are most critical)
│   └── Kullanıcıların %70+'ı sadece ilk 3'e bakar
├── "Hero frame" — en etkileyici özelliği ilk sıraya koyun
├── Her ekran görüntüsünde bir özellik vurgulayın (highlight one feature each)
├── Açıklayıcı metin overlay ekleyin (add descriptive text overlay)
├── Tutarlı tasarım dili (consistent design language)
├── Gerçek uygulama ekranları kullanın (use real app screens)
└── Video preview — App Store'da 30 saniye (30 sec video preview on App Store)
Ekran Görüntüsü Şablonu (Screenshot Template):
┌─────────────────────┐
│   "Anında planla,   │  ← Başlık metni (headline text)
│    kolayca takip et" │
│                     │
│  ┌───────────────┐  │
│  │               │  │
│  │  Uygulama     │  │  ← Gerçek uygulama ekranı (actual app screen)
│  │  Ekranı       │  │
│  │               │  │
│  └───────────────┘  │
│                     │
│   ● ○ ○ ○ ○        │  ← Sayfa göstergesi (page indicator)
└─────────────────────┘

3.5 Açıklama Yazımı ve Derecelendirme (Description & Ratings)

Açıklama Yazım Teknikleri (Description Writing Tips)

Yapı Önerisi (Recommended Structure):
├── 1. paragraf: Ana değer önerisi (main value proposition)
│   └── İlk 1-3 satır "daha fazla" butonundan önce görünür
├── 2. paragraf: Temel özellikler listesi (key features — bullet points)
├── 3. paragraf: Kullanıcı yorumları / ödüller (testimonials / awards)
├── 4. paragraf: Abonelik / fiyatlandırma bilgisi (subscription / pricing)
└── Son: İletişim bilgileri, sosyal medya linkleri

Derecelendirme Yönetimi (Rating Management)

Derecelendirme Stratejisi (Rating Strategy):
├── Doğru zamanda sor (ask at the right time)
│   ├── ✅ Kullanıcı bir görevi tamamladıktan sonra (after completing a task)
│   ├── ✅ Olumlu bir deneyim yaşadıktan sonra (after a positive experience)
│   ├── ❌ Uygulama ilk açıldığında (on first launch)
│   └── ❌ Olumsuz bir deneyim sırasında (during negative experience)
├── iOS: SKStoreReviewController.requestReview()
│   └── Apple yılda 3 kez gösterir (shown max 3 times per year)
├── Android: ReviewManager (In-App Review API)
│   └── Google gösterim sıklığını kontrol eder
├── Olumsuz yorumlara yanıt verin (respond to negative reviews)
│   └── Çözüm sunun, kibar olun, güncellemeden sonra tekrar deneyin
└── Ortalama 4.0+ hedefleyin (target 4.0+ average rating)

3.6 Lokalizasyon ve A/B Test

Lokalizasyon (Localization)

Lokalizasyon Kontrol Listesi (Localization Checklist):
├── Uygulama adı ve subtitle'ı çevir (translate name & subtitle)
├── Anahtar kelimeleri yerelleştir (localize keywords)
├── Açıklamayı çevir (translate description)
├── Ekran görüntülerini yerelleştir (localize screenshots)
│   └── Overlay metinleri, cihaz dili, tarih/saat formatı
├── Öncelikli diller (priority languages):
│   ├── İngilizce (English) — en büyük pazar
│   ├── İspanyolca (Spanish) — 2. en büyük
│   ├── Portekizce (Portuguese) — Brezilya pazarı
│   ├── Almanca (German) — yüksek gelir
│   ├── Japonca (Japanese) — yüksek ARPU
│   └── Kore dili (Korean) — mobil odaklı pazar
└── Kültürel uyum (cultural adaptation)
    └── Renkler, ikonlar, görseller kültüre uygun olmalı

A/B Test (Store Listing Experiments)

PlatformDesteklenen A/B Testler
Google Playİkon, ekran görüntüleri, açıklama, öne çıkan görsel
App Storeİkon, ekran görüntüleri, uygulama preview videosu (Product Page Optimization)
Google Play A/B Test Süreci:
1. Play Console > Store Listing > Store listing experiments
2. Test türünü seç (graphics veya description)
3. Varyant oluştur (create variant)
4. Trafik dağılımını ayarla (set traffic allocation)
5. Min 7 gün çalıştır (run for min 7 days)
6. Kazanan varyantı uygula (apply winning variant)

3.7 ASO — Resmi Linkler

KaynakLink
App Store Product Page Optimizationhttps://developer.apple.com/app-store/product-page
Google Play Store Listing Experimentshttps://support.google.com/googleplay/android-developer/answer/6227309
Google Play ASO Guidehttps://developer.android.com/distribute/best-practices/grow/store-listing

4. Monetization — Gelir Modelleri (Revenue Models)

4.1 Gelir Modeli Türleri (Revenue Model Types)

ModelAçıklamaÖrnek Uygulamalar
Free (Ücretsiz)Tamamen ücretsiz, reklam yokAçık kaynak, kurumsal araçlar
FreemiumTemel özellikler ücretsiz, premium ücretliSpotify, Canva, Evernote
Subscription (Abonelik)Aylık/yıllık ücretNetflix, Headspace, Notion
One-time Purchase (Tek seferlik)Bir kez öde, her zaman kullanProcreate, Dark Sky
In-App Purchase (IAP)Uygulama içi satın alma — özellik/içerikOyunlar, fotoğraf filtreleri
Ad-supported (Reklam destekli)Ücretsiz, reklam geliriOyunlar, haber uygulamaları
Hybrid (Karma)Reklam + IAP + AbonelikDuolingo (reklam + premium)

4.2 Reklam Tipleri (Ad Types)

Reklam TürüAçıklamaeCPM (ortalama)Kullanıcı Deneyimi
BannerEkran alt/üstünde sürekli gösterim$0.5-2⭐ Düşük etki (low impact)
InterstitialTam ekran, geçiş noktalarında$5-15⭐⭐ Orta etki (medium impact)
RewardedÖdül karşılığı izlenen video$10-30⭐⭐⭐ Yüksek kabul (high acceptance)
Nativeİçeriğe entegre, doğal görünüm$5-20⭐⭐⭐ Düşük rahatsızlık (low annoyance)
App OpenUygulama açılışında gösterilen$5-10⭐⭐ Orta etki
Reklam Yerleşim Stratejisi (Ad Placement Strategy):
├── Banner: Listeleme ekranları, ana sayfa alt kısmı
├── Interstitial: Seviye geçişleri, ekran geçişleri
│   └── ⚠️ Her 2-3 aksiyonda bir gösterin, daha sık değil
├── Rewarded: Ekstra hayat, bonus içerik, premium özellik deneme
│   └── ✅ Kullanıcı kendi isteğiyle izler — en yüksek gelir
├── Native: Feed içi, içerik arası
│   └── ✅ Kullanıcı deneyimini en az bozan format
└── App Open: Splash screen sonrası
    └── ⚠️ Dikkatli kullanın — ilk izlenimi olumsuz etkileyebilir

4.3 AdMob Entegrasyonu (AdMob Integration)

AdMob Kurulum Adımları (Setup Steps):
├── 1. AdMob hesabı oluştur: https://admob.google.com
├── 2. Uygulama ekle (add app)
├── 3. Reklam birimi oluştur (create ad unit)
├── 4. App ID ve Ad Unit ID'yi not al
├── 5. SDK entegrasyonu yap
└── 6. Test reklamları ile doğrula (verify with test ads)

React Native (react-native-google-mobile-ads)

typescript
// React Native AdMob entegrasyonu

// 1. Kurulum (installation)
// npm install react-native-google-mobile-ads

// 2. app.json yapılandırması
// {
//   "react-native-google-mobile-ads": {
//     "android_app_id": "ca-app-pub-xxxxx~xxxxx",
//     "ios_app_id": "ca-app-pub-xxxxx~xxxxx"
//   }
// }

// 3. Banner reklam (Banner Ad)
import { BannerAd, BannerAdSize, TestIds } from 'react-native-google-mobile-ads';

const adUnitId = __DEV__
  ? TestIds.BANNER  // Test reklam ID'si (test ad ID)
  : 'ca-app-pub-xxxxx/xxxxx';  // Gerçek reklam ID'si (production ad ID)

function MyScreen() {
  return (
    <BannerAd
      unitId={adUnitId}
      size={BannerAdSize.ANCHORED_ADAPTIVE_BANNER}
      requestOptions={{ requestNonPersonalizedAdsOnly: true }}
    />
  );
}

// 4. Interstitial reklam (Interstitial Ad)
import { InterstitialAd, AdEventType, TestIds } from 'react-native-google-mobile-ads';

const interstitial = InterstitialAd.createForAdRequest(TestIds.INTERSTITIAL);

interstitial.addAdEventListener(AdEventType.LOADED, () => {
  interstitial.show();  // Yüklenince göster (show when loaded)
});

interstitial.load();  // Önceden yükle (preload)

// 5. Rewarded reklam (Rewarded Ad)
import { RewardedAd, RewardedAdEventType, TestIds } from 'react-native-google-mobile-ads';

const rewarded = RewardedAd.createForAdRequest(TestIds.REWARDED);

rewarded.addAdEventListener(RewardedAdEventType.EARNED_REWARD, (reward) => {
  console.log(`Ödül kazanıldı: ${reward.amount} ${reward.type}`);
  // Kullanıcıya ödülü ver (grant reward to user)
});

rewarded.load();

Flutter (google_mobile_ads)

dart
// Flutter AdMob entegrasyonu

// 1. pubspec.yaml
// dependencies:
//   google_mobile_ads: ^4.0.0

// 2. Başlatma (initialization)
import 'package:google_mobile_ads/google_mobile_ads.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();  // AdMob SDK başlat
  runApp(MyApp());
}

// 3. Banner reklam (Banner Ad)
class BannerAdWidget extends StatefulWidget {
  @override
  _BannerAdWidgetState createState() => _BannerAdWidgetState();
}

class _BannerAdWidgetState extends State<BannerAdWidget> {
  BannerAd? _bannerAd;
  bool _isLoaded = false;

  @override
  void initState() {
    super.initState();
    _bannerAd = BannerAd(
      adUnitId: 'ca-app-pub-xxxxx/xxxxx',  // Test: BannerAd.testAdUnitId
      size: AdSize.banner,
      request: AdRequest(),
      listener: BannerAdListener(
        onAdLoaded: (ad) => setState(() => _isLoaded = true),
        onAdFailedToLoad: (ad, error) => ad.dispose(),
      ),
    )..load();
  }

  @override
  Widget build(BuildContext context) {
    if (!_isLoaded || _bannerAd == null) return SizedBox.shrink();
    return SizedBox(
      width: _bannerAd!.size.width.toDouble(),
      height: _bannerAd!.size.height.toDouble(),
      child: AdWidget(ad: _bannerAd!),
    );
  }

  @override
  void dispose() {
    _bannerAd?.dispose();
    super.dispose();
  }
}

4.4 RevenueCat — Abonelik Yönetimi (Subscription Management)

RevenueCat, iOS ve Android abonelik yönetimini basitleştirir (simplifies subscription management).

RevenueCat Avantajları:
├── Tek SDK — hem iOS hem Android (single SDK — both platforms)
├── Server-side receipt validation (sunucu tarafı doğrulama)
├── Webhook desteği (backend entegrasyonu)
├── Analitik dashboard (gelir, churn, MRR, LTV)
├── A/B test desteği (paywall experiments)
├── Ücretsiz plan: $2.5K MRR'a kadar (free up to $2.5K MRR)
└── Entitlements sistemi — erişim yönetimi
typescript
// React Native RevenueCat entegrasyonu

// 1. Kurulum (installation)
// npm install react-native-purchases

import Purchases from 'react-native-purchases';

// 2. Başlatma (initialization)
await Purchases.configure({
  apiKey: Platform.OS === 'ios'
    ? 'appl_YOUR_IOS_KEY'
    : 'goog_YOUR_ANDROID_KEY',
});

// 3. Mevcut teklifleri getir (fetch available offerings)
const offerings = await Purchases.getOfferings();
if (offerings.current) {
  const packages = offerings.current.availablePackages;
  // Paketleri kullanıcıya göster (display packages to user)
  // packages[0].product.priceString — "$9.99"
  // packages[0].product.title — "Premium Monthly"
}

// 4. Satın alma (make purchase)
try {
  const { customerInfo } = await Purchases.purchasePackage(selectedPackage);
  if (customerInfo.entitlements.active['premium']) {
    // Premium erişim aktif (premium access granted)
  }
} catch (e) {
  if (!e.userCancelled) {
    console.error('Satın alma hatası:', e);
  }
}

// 5. Abonelik durumunu kontrol et (check subscription status)
const customerInfo = await Purchases.getCustomerInfo();
const isPremium = customerInfo.entitlements.active['premium'] !== undefined;

// 6. Restore purchases (satın almaları geri yükle)
const { customerInfo } = await Purchases.restorePurchases();

4.5 Komisyon Oranları Tablosu (Commission Rates)

PlatformStandart KomisyonDüşük KomisyonKoşul
Apple App Store%30%15Small Business Program ($1M altı yıllık gelir)
Google Play%15 (ilk $1M)%15İlk $1M otomatik (%30 sonrası)
Google Play Abonelik%15%15Tüm abonelikler (all subscriptions)
Apple Abonelik (1. yıl)%30%15SBP üyeleri
Apple Abonelik (2. yıl+)%15%15Kullanıcı 1+ yıl abone kalırsa

💡 İpucu: Apple Small Business Program'a başvuru: https://developer.apple.com/app-store/small-business-program — yıllık $1M altı gelir koşuluyla komisyon %30'dan %15'e düşer.

4.6 Karar Tablosu — Hangi Model Ne Zaman? (Decision Table)

Uygulama TürüÖnerilen ModelNeden
Utility (araç)Freemium / One-timeKullanıcılar düzenli ödeme yapmak istemez
Sosyal medyaFree + ReklamBüyük kullanıcı tabanı gerekli
Oyun (Casual)Free + Reklam + IAPRewarded ads + satın alınabilir içerik
Oyun (Premium)One-timeYüksek kaliteli, bağımsız oyunlar
İçerik / MedyaSubscriptionSürekli güncellenen içerik
EğitimFreemium / SubscriptionTemel ücretsiz, gelişmiş ücretli
Sağlık / FitnessSubscriptionSürekli motivasyon ve içerik
Verimlilik (Productivity)Freemium / SubscriptionTemel özellikler ücretsiz, pro özellikler ücretli
B2B / SaaSSubscriptionİşletme bütçesi döngüsel
E-ticaretFree + KomisyonÜcretsiz indir, satış komisyonu

5. Release Yönetimi (Release Management)

5.1 Alpha → Beta → Production Akışı

Release Akışı (Release Flow):
┌────────┐    ┌──────────┐    ┌───────────┐    ┌────────────┐
│ Alpha  │───▶│  Beta    │───▶│  Release  │───▶│ Production │
│ (Dev)  │    │ (Test)   │    │ Candidate │    │ (Canlı)    │
│        │    │          │    │  (RC)     │    │            │
└────────┘    └──────────┘    └───────────┘    └────────────┘
  Dahili        Sınırlı         Son             Tüm
  test          kullanıcı       kontroller      kullanıcılar
                                (QA sign-off)
AşamaAmaçKullanıcılarSüre
AlphaErken geliştirme testi (early dev testing)Geliştirici ekipSürekli (continuous)
BetaÖzellik testi, geri bildirim (feature test)Seçili kullanıcılar / beta testers1-4 hafta
RC (Release Candidate)Son kontrol, stabilite testiQA ekibi + seçili kullanıcılar3-7 gün
ProductionCanlı yayın (live release)Tüm kullanıcılar

5.2 Staged Rollout — Kademeli Yayınlama

Staged Rollout Stratejisi (Staged Rollout Strategy):
     %1          %5          %20         %50         %100
      │           │           │           │           │
      ▼           ▼           ▼           ▼           ▼
  ┌───────┐  ┌───────┐  ┌───────┐  ┌───────┐  ┌───────┐
  │ Day 1 │  │ Day 2 │  │ Day 4 │  │ Day 7 │  │Day 14 │
  │       │  │       │  │       │  │       │  │       │
  │Monitor│  │Monitor│  │Monitor│  │Monitor│  │ Full  │
  │ crash │  │ crash │  │ crash │  │ crash │  │release│
  │ rates │  │ rates │  │ rates │  │ rates │  │       │
  └───────┘  └───────┘  └───────┘  └───────┘  └───────┘
PlatformStaged Rollout DesteğiKontrol
Google Play✅ Yüzde bazlı (percentage-based)%1 - %100 arası ayarlanabilir
App Store✅ Phased release (7 gün otomatik)Durdurulabilir (can be paused)
Google Play Staged Rollout:
├── Play Console > Release > Production > Create new release
├── Rollout percentage ayarla (set rollout percentage)
├── İzle: crash rate, ANR rate, kullanıcı yorumları
├── Sorun varsa → rollout'u duraklat (halt rollout)
├── Sorun yoksa → yüzdeyi artır (increase percentage)
└── Tam yayın (full rollout) — %100

App Store Phased Release:
├── App Store Connect > App Version > Phased Release
├── 7 gün boyunca otomatik artış (automatic increase over 7 days):
│   Day 1: %1, Day 2: %2, Day 3: %5, Day 4: %10,
│   Day 5: %20, Day 6: %50, Day 7: %100
├── Duraklatılabilir (can be paused)
├── İptal edilip hemen %100 yapılabilir (can release immediately to all)
└── "Update Available" gören kullanıcılar her zaman indirebilir

5.3 Rollback ve Hotfix Süreci (Rollback & Hotfix)

Rollback Karar Ağacı (Rollback Decision Tree):
                    ┌─────────────────┐
                    │ Kritik sorun mu? │
                    │ (Critical issue?)│
                    └────────┬────────┘
                    ┌────────┴────────┐
                    ▼                 ▼
               ┌────────┐       ┌────────┐
               │  Evet  │       │  Hayır │
               │  (Yes) │       │  (No)  │
               └───┬────┘       └───┬────┘
                   ▼                ▼
          ┌──────────────┐  ┌──────────────┐
          │ Staged       │  │ Hotfix       │
          │ rollout      │  │ hazırla      │
          │ duraklat     │  │ (Prepare     │
          │ (Halt)       │  │  hotfix)     │
          └──────┬───────┘  └──────────────┘

     ┌───────────────────┐
     │ Önceki versiyona  │
     │ rollback mümkün?  │
     └────────┬──────────┘
     ┌────────┴────────┐
     ▼                 ▼
┌─────────┐     ┌──────────┐
│ Google  │     │ Apple    │
│ Play:   │     │ App Store│
│ Rollback│     │ Rollback │
│ ✅ Var  │     │ ❌ Yok   │
└─────────┘     └──────────┘
PlatformRollbackHotfix Süreci
Google Play✅ Önceki sürüme geri alınabilir (can revert to previous version)Yeni build yükle, staged rollout
App Store❌ Rollback yok — yeni versiyon göndermeliYeni build, expedited review talep et
bash
# Hotfix süreci (Hotfix process):
# 1. Sorunu tespit et (identify the issue)
# 2. Hotfix branch oluştur (create hotfix branch)
git checkout -b hotfix/v1.2.1 main

# 3. Sorunu düzelt (fix the issue)
# 4. Versiyon numarasını artır (bump version)
# 5. Build oluştur (create build)
# 6. Test et (test)
# 7. Mağazaya yükle (upload to store)
# 8. Apple: Expedited review talep et (request expedited review)
# 9. Google: Staged rollout ile hızlı yayınla

5.4 Changelog Yazımı (Writing Changelogs)

Changelog Best Practices:
├── Kullanıcı odaklı dil kullanın (use user-focused language)
│   ├── ✅ "Fotoğraflar artık daha hızlı yükleniyor" (Photos now load faster)
│   ├── ❌ "Image loading optimizasyonu yapıldı" (too technical)
│   └── ❌ "Bug fix" (too vague — çok belirsiz)
├── Kategori kullanın (use categories):
│   ├── 🆕 Yeni özellikler (New features)
│   ├── ✨ İyileştirmeler (Improvements)
│   ├── 🐛 Hata düzeltmeleri (Bug fixes)
│   └── 🔒 Güvenlik güncellemeleri (Security updates)
├── Kısa ve öz tutun (keep it concise)
└── Her güncelleme için yazın — "Bug fixes and improvements" yazmayın
Örnek Changelog (Example):
v2.1.0 — 11 Nisan 2026

🆕 Yeni Özellikler:
• Karanlık mod desteği eklendi (Dark mode support)
• Fotoğraf düzenleme araçları (Photo editing tools)

✨ İyileştirmeler:
• Uygulama açılış hızı %40 iyileştirildi (40% faster launch)
• Arama sonuçları daha doğru (improved search results)

🐛 Hata Düzeltmeleri:
• Bildirimler bazen görünmüyordu — düzeltildi (notifications fix)
• Profil fotoğrafı yükleme hatası giderildi (profile photo upload fix)

5.5 Feature Flags — Özellik Bayrakları

Feature flags, özellikleri kod dağıtımından bağımsız olarak açıp kapatmanızı sağlar (toggle features independently from code deployment).

Feature Flag Araçları (Tools):
├── Firebase Remote Config (ücretsiz / free)
│   └── Google ekosistemi, basit key-value yapılandırma
├── LaunchDarkly (ücretli / paid)
│   └── Enterprise, gelişmiş hedefleme, A/B test
├── Unleash (açık kaynak / open source)
│   └── Self-hosted seçeneği var
├── Flagsmith (açık kaynak + SaaS)
│   └── Self-hosted veya cloud
└── ConfigCat (ücretli)
    └── Basit, hızlı entegrasyon
typescript
// Firebase Remote Config örneği (React Native)

import remoteConfig from '@react-native-firebase/remote-config';

// 1. Varsayılan değerler ayarla (set defaults)
await remoteConfig().setDefaults({
  new_onboarding_enabled: false,      // Yeni onboarding aktif mi?
  max_free_photos: 10,                // Ücretsiz fotoğraf limiti
  show_premium_banner: true,          // Premium banner göster
  maintenance_mode: false,            // Bakım modu
});

// 2. Sunucudan değerleri çek (fetch from server)
await remoteConfig().setConfigSettings({
  minimumFetchIntervalMillis: 3600000, // 1 saat cache (1 hour cache)
});
await remoteConfig().fetchAndActivate();

// 3. Değerleri kullan (use values)
const isNewOnboarding = remoteConfig().getValue('new_onboarding_enabled').asBoolean();
const maxPhotos = remoteConfig().getValue('max_free_photos').asNumber();

if (isNewOnboarding) {
  // Yeni onboarding göster (show new onboarding)
} else {
  // Eski onboarding göster (show old onboarding)
}
Feature Flag Kullanım Senaryoları:
├── Kademeli özellik açma (gradual feature rollout)
│   └── %10 kullanıcıya aç → izle → %100'e çıkar
├── A/B test
│   └── Hangi tasarım daha iyi dönüşüm sağlıyor?
├── Kill switch (acil kapatma)
│   └── Sorunlu özelliği anında kapat — yeni build gerektirmez
├── Bakım modu (maintenance mode)
│   └── Backend bakımda iken kullanıcıya mesaj göster
└── Kullanıcı segmentasyonu (user targeting)
    └── Premium kullanıcılara farklı deneyim

5.6 Versiyonlama — SemVer + Build Number

SemVer (Semantic Versioning):
  MAJOR.MINOR.PATCH
    │      │     │
    │      │     └── Hata düzeltmeleri (bug fixes) — geriye uyumlu
    │      └──────── Yeni özellikler (new features) — geriye uyumlu
    └─────────────── Kırılıcı değişiklikler (breaking changes)

Örnekler:
  1.0.0 → İlk yayın (initial release)
  1.1.0 → Yeni özellik eklendi (new feature added)
  1.1.1 → Bug fix
  2.0.0 → Büyük güncelleme, eski API uyumsuz (major update)
PlatformVersionBuild NumberAçıklama
AndroidversionNameversionCodeversionCode her yüklemede artmalı (integer)
iOSCFBundleShortVersionStringCFBundleVersionBuild number her yüklemede artmalı
groovy
// Android — build.gradle
android {
    defaultConfig {
        versionCode 15           // Her upload'da artır (increment each upload)
        versionName "2.1.0"      // Kullanıcının gördüğü versiyon
    }
}
xml
<!-- iOS — Info.plist -->
<key>CFBundleShortVersionString</key>
<string>2.1.0</string>        <!-- Kullanıcının gördüğü versiyon -->
<key>CFBundleVersion</key>
<string>15</string>            <!-- Her upload'da artır -->
json
// Expo — app.json
{
  "expo": {
    "version": "2.1.0",
    "ios": {
      "buildNumber": "15"
    },
    "android": {
      "versionCode": 15
    }
  }
}
bash
# Otomatik versiyon artırma (automatic version bumping)
# npm version kullanarak (using npm version)
npm version patch   # 2.1.0 → 2.1.1
npm version minor   # 2.1.1 → 2.2.0
npm version major   # 2.2.0 → 3.0.0

6. CI/CD Mobil (Mobile CI/CD)

6.1 Fastlane — iOS + Android Otomasyon

Fastlane, mobil uygulama build, test ve dağıtım sürecini otomatikleştirir (automates build, test, and deployment).

bash
# Fastlane kurulumu (installation)
# macOS
brew install fastlane

# Ruby gem
gem install fastlane

# Proje dizininde başlat (initialize in project directory)
fastlane init

iOS Fastfile

ruby
# ios/fastlane/Fastfile

default_platform(:ios)

platform :ios do

  # Sertifika yönetimi (certificate management)
  desc "Sertifikaları senkronize et (sync certificates)"
  lane :certificates do
    match(type: "appstore")   # App Store sertifikası
  end

  # Beta dağıtım — TestFlight
  desc "TestFlight'a yükle (upload to TestFlight)"
  lane :beta do
    increment_build_number    # Build numarasını artır
    match(type: "appstore")   # Sertifikayı al

    build_app(                # Archive oluştur
      workspace: "MyApp.xcworkspace",
      scheme: "MyApp",
      configuration: "Release",
      export_method: "app-store"
    )

    upload_to_testflight      # TestFlight'a yükle
    slack(message: "iOS beta build TestFlight'a yüklendi! 🚀")
  end

  # Production — App Store
  desc "App Store'a yükle (upload to App Store)"
  lane :release do
    increment_build_number
    match(type: "appstore")

    build_app(
      workspace: "MyApp.xcworkspace",
      scheme: "MyApp",
      configuration: "Release",
      export_method: "app-store"
    )

    upload_to_app_store(
      skip_metadata: false,
      skip_screenshots: true,
      submit_for_review: true,  # Otomatik incelemeye gönder
      automatic_release: true   # Onay sonrası otomatik yayınla
    )
  end
end

Android Fastfile

ruby
# android/fastlane/Fastfile

default_platform(:android)

platform :android do

  # Beta dağıtım — Internal test track
  desc "Internal test track'e yükle"
  lane :beta do
    gradle(
      task: "bundle",
      build_type: "Release"
    )

    upload_to_play_store(
      track: "internal",         # internal / alpha / beta / production
      aab: "app/build/outputs/bundle/release/app-release.aab"
    )

    slack(message: "Android beta build Play Store internal track'e yüklendi!")
  end

  # Production — Play Store
  desc "Play Store'a yükle (upload to Play Store)"
  lane :release do
    gradle(
      task: "bundle",
      build_type: "Release"
    )

    upload_to_play_store(
      track: "production",
      rollout: "0.1",            # %10 staged rollout ile başla
      aab: "app/build/outputs/bundle/release/app-release.aab"
    )
  end

  # Staged rollout artır (increase staged rollout)
  desc "Rollout yüzdesini artır"
  lane :increase_rollout do |options|
    upload_to_play_store(
      track: "production",
      rollout: options[:percentage],  # Örn: "0.5" = %50
      skip_upload_aab: true
    )
  end
end
bash
# Fastlane komutları (commands)
fastlane ios beta              # iOS TestFlight build
fastlane ios release           # iOS App Store release
fastlane android beta          # Android internal test
fastlane android release       # Android production release
fastlane android increase_rollout percentage:0.5  # %50 rollout

6.2 EAS Build — Expo Otomasyon

bash
# EAS Build + Submit tam akış (full flow)

# 1. Build oluştur (create build)
eas build --platform all --profile production

# 2. Mağazaya gönder (submit to stores)
eas submit --platform ios --profile production
eas submit --platform android --profile production

# 3. Build + Submit birlikte (combined)
eas build --platform all --profile production --auto-submit

# 4. EAS Update — OTA güncelleme (over-the-air update)
eas update --branch production --message "Bug fix: login ekranı düzeltildi"
json
// eas.json — tam yapılandırma (full configuration)
{
  "cli": {
    "version": ">= 5.0.0"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal",
      "android": { "buildType": "apk" },
      "ios": { "simulator": false }
    },
    "production": {
      "android": { "buildType": "app-bundle" },
      "ios": { "buildConfiguration": "Release" },
      "env": {
        "API_URL": "https://api.myapp.com",
        "SENTRY_DSN": "https://xxxxx@sentry.io/xxxxx"
      }
    }
  },
  "submit": {
    "production": {
      "ios": {
        "appleId": "your@email.com",
        "ascAppId": "123456789",
        "appleTeamId": "TEAM_ID"
      },
      "android": {
        "serviceAccountKeyPath": "./google-service-account.json",
        "track": "internal"
      }
    }
  }
}

6.3 Codemagic — Flutter CI/CD

yaml
# codemagic.yaml — Flutter yapılandırması

workflows:
  flutter-android-release:
    name: Flutter Android Release
    max_build_duration: 30
    instance_type: mac_mini_m1

    environment:
      groups:
        - google_play_credentials    # Play Store service account
        - keystore_credentials       # Keystore bilgileri
      flutter: stable
      xcode: latest

    scripts:
      - name: Flutter bağımlılıkları kur (install dependencies)
        script: flutter pub get

      - name: Testleri çalıştır (run tests)
        script: flutter test

      - name: Android AAB oluştur (build Android AAB)
        script: |
          flutter build appbundle --release \
            --build-number=$PROJECT_BUILD_NUMBER

    artifacts:
      - build/app/outputs/bundle/release/*.aab

    publishing:
      google_play:
        credentials: $GCLOUD_SERVICE_ACCOUNT_CREDENTIALS
        track: internal
        submit_as_draft: false

  flutter-ios-release:
    name: Flutter iOS Release
    max_build_duration: 60
    instance_type: mac_mini_m1

    environment:
      groups:
        - app_store_credentials
        - ios_signing
      flutter: stable
      xcode: latest
      cocoapods: default

    scripts:
      - name: Flutter bağımlılıkları kur
        script: flutter pub get

      - name: CocoaPods kur
        script: cd ios && pod install

      - name: iOS build
        script: |
          flutter build ipa --release \
            --build-number=$PROJECT_BUILD_NUMBER \
            --export-options-plist=ios/ExportOptions.plist

    artifacts:
      - build/ios/ipa/*.ipa

    publishing:
      app_store_connect:
        api_key: $APP_STORE_CONNECT_API_KEY
        key_id: $APP_STORE_CONNECT_KEY_ID
        issuer_id: $APP_STORE_CONNECT_ISSUER_ID
        submit_to_testflight: true

6.4 GitHub Actions — Mobil Workflow

Android Build + Deploy

yaml
# .github/workflows/android-release.yml
name: Android Release

on:
  push:
    tags:
      - 'v*'  # v1.0.0 gibi tag'lerde tetikle (trigger on version tags)

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Java kurulumu (Setup Java)
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Flutter kurulumu (Setup Flutter)
        uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.24.0'
          channel: 'stable'

      - name: Bağımlılıkları kur (Install dependencies)
        run: flutter pub get

      - name: Testleri çalıştır (Run tests)
        run: flutter test

      - name: Keystore decode
        run: |
          echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/keystore.jks

      - name: AAB oluştur (Build AAB)
        run: |
          flutter build appbundle --release \
            --build-number=${{ github.run_number }}
        env:
          KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
          KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
          KEY_ALIAS: ${{ secrets.KEY_ALIAS }}

      - name: Play Store'a yükle (Upload to Play Store)
        uses: r0adkll/upload-google-play@v1
        with:
          serviceAccountJsonPlainText: ${{ secrets.PLAY_STORE_SERVICE_ACCOUNT }}
          packageName: com.example.myapp
          releaseFiles: build/app/outputs/bundle/release/app-release.aab
          track: internal
          status: completed

iOS Build + Deploy

yaml
# .github/workflows/ios-release.yml
name: iOS Release

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    runs-on: macos-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Flutter kurulumu (Setup Flutter)
        uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.24.0'
          channel: 'stable'

      - name: Bağımlılıkları kur (Install dependencies)
        run: flutter pub get

      - name: CocoaPods kur (Install CocoaPods)
        run: cd ios && pod install

      - name: iOS sertifika kurulumu (Setup iOS signing)
        uses: apple-actions/import-codesign-certs@v2
        with:
          p12-file-base64: ${{ secrets.IOS_P12_BASE64 }}
          p12-password: ${{ secrets.IOS_P12_PASSWORD }}

      - name: Provisioning profile kur (Install provisioning profile)
        uses: apple-actions/download-provisioning-profiles@v2
        with:
          bundle-id: com.example.myapp
          issuer-id: ${{ secrets.APP_STORE_ISSUER_ID }}
          api-key-id: ${{ secrets.APP_STORE_KEY_ID }}
          api-private-key: ${{ secrets.APP_STORE_PRIVATE_KEY }}

      - name: IPA oluştur (Build IPA)
        run: |
          flutter build ipa --release \
            --build-number=${{ github.run_number }} \
            --export-options-plist=ios/ExportOptions.plist

      - name: App Store Connect'e yükle (Upload to App Store Connect)
        uses: apple-actions/upload-testflight-build@v2
        with:
          app-path: build/ios/ipa/MyApp.ipa
          issuer-id: ${{ secrets.APP_STORE_ISSUER_ID }}
          api-key-id: ${{ secrets.APP_STORE_KEY_ID }}
          api-private-key: ${{ secrets.APP_STORE_PRIVATE_KEY }}

6.5 CodePush / Expo Updates — OTA Güncellemeler

OTA (Over-The-Air) güncellemeler, mağaza incelemesi olmadan JavaScript/asset güncellemeleri göndermenizi sağlar (push JS/asset updates without store review).

OTA Güncelleme Araçları:
├── Expo Updates (EAS Update)
│   └── Expo / React Native (Expo)
├── CodePush (App Center — Microsoft)
│   └── React Native (bare workflow) — ⚠️ 2025'te retired
├── Shorebird (Flutter)
│   └── Flutter için OTA — Dart kodu güncellenebilir
└── expo-updates (bare React Native)
    └── Expo Updates bare workflow'da
bash
# EAS Update — Expo OTA güncellemeler

# 1. EAS Update yapılandır (configure)
eas update:configure

# 2. Güncelleme gönder (push update)
eas update --branch production --message "Login ekranı düzeltildi (login screen fix)"

# 3. Belirli platforma güncelleme (platform-specific update)
eas update --branch production --platform ios --message "iOS specific fix"

# 4. Güncelleme geçmişini gör (view update history)
eas update:list

# 5. Güncellemeyi geri al (rollback update)
eas update:rollback --branch production
OTA vs Mağaza Güncellemesi — Ne Zaman Hangisi?
├── OTA kullanılabilir (OTA can be used):
│   ├── ✅ JavaScript / TypeScript kod değişiklikleri
│   ├── ✅ Stil / UI değişiklikleri (style changes)
│   ├── ✅ Resim / asset değişiklikleri
│   ├── ✅ Bug fix — JS tarafında
│   └── ✅ Metin / çeviri güncellemeleri

└── Mağaza güncellemesi gerekli (Store update required):
    ├── ❌ Native kod değişikliği (native module changes)
    ├── ❌ Yeni native bağımlılık (new native dependency)
    ├── ❌ İzin değişiklikleri (permission changes)
    ├── ❌ App icon / splash screen değişikliği
    └── ❌ SDK versiyon güncellemesi (SDK version update)

7. Android vs iOS Karşılaştırma Tablosu (Comparison Table)

ÖzellikAndroid (Google Play)iOS (App Store)
Geliştirici hesabıGoogle Play ConsoleApple Developer Program
Kayıt ücreti$25 tek seferlik (one-time)$99/yıl (annual)
Build formatıAAB (zorunlu / required)IPA (via Xcode Archive)
İmzalamaKeystore + Play App SigningSertifika + Provisioning Profile
Test aracıInternal/Closed/Open test tracksTestFlight
İnceleme süresi1-3 gün (1-3 days)1-7 gün (1-7 days)
İnceleme katılığıOrta (moderate)Yüksek (strict)
Staged rollout✅ Yüzde bazlı (manual %)✅ Phased release (7 gün otomatik)
Rollback✅ Önceki sürüme geri alınabilir❌ Yeni build göndermeli
OTA güncelleme✅ (JS/Dart kodu için)✅ (JS/Dart kodu için)
Komisyon oranı%15 (ilk $1M), sonra %30%30 (%15 SBP ile)
Abonelik komisyonu%15%30 (1. yıl), %15 (2. yıl+)
Ödeme zorunluluğuPlay Billing (dijital içerik)Apple IAP (dijital içerik)
Sideload (harici kurulum)✅ APK ile mümkün❌ Jailbreak hariç mümkün değil
Minimum OS desteğiAPI 21 (Android 5.0) önerileniOS 16+ önerilen
Dağıtım esnekliğiAPK dağıtımı, alternatif mağazalarSadece App Store (Enterprise hariç)
A/B test✅ Store listing experiments✅ Product page optimization
Uygulama boyutu limiti150 MB AAB (+ asset packs)4 GB (cellular: 200 MB limit)

RehberAçıklama
React Native RehberiReact Native ile mobil uygulama geliştirme
Flutter RehberiFlutter ile cross-platform geliştirme
Docker RehberiCI/CD altyapısı için Docker
Figma RehberiMobil UI tasarımı

Developer Guides & Technical References