📱 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)
| Özellik | Bireysel (Personal) | Organizasyon (Organization) |
|---|---|---|
| Kayıt ücreti | $25 | $25 |
| Kimlik doğrulama | Kişisel ID | D-U-N-S + Kişisel ID |
| Geliştirici adı | Kişisel isim | Şirket adı |
| İletişim bilgisi | Kişisel | Kurumsal |
| Uygun kullanım | Bireysel projeler | Şirket uygulamaları |
# 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ı.
| Özellik | APK | AAB (App Bundle) |
|---|---|---|
| Tam adı | Android Package | Android App Bundle |
| Uzantı | .apk | .aab |
| Google Play | ❌ Artık kabul edilmiyor (no longer accepted) | ✅ Zorunlu (required) |
| Boyut optimizasyonu | Yok — tüm kaynaklar dahil | ✅ Cihaza özel APK üretilir |
| Dosya boyutu | Daha büyük (larger) | %15-20 daha küçük (smaller) |
| Doğrudan kurulum | ✅ Evet (sideload) | ❌ Hayır — Play Store gerekli |
| İmzalama (Signing) | Geliştirici imzalar | Play 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)
# 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)
// 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# 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 gerekir1.4 Build — Release APK/AAB Oluşturma
Native Android (Gradle)
# 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.apkFlutter
# 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.apkReact Native
# 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=releaseExpo (EAS Build)
# 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// 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ür | Boyut | Adet |
|---|---|---|
| Telefon (Phone) | 16:9 veya 9:16, min 320px, max 3840px | Min 2, Max 8 |
| 7" Tablet | 16:9 veya 9:16 | Opsiyonel, Max 8 |
| 10" Tablet | 16:9 veya 9:16 | Opsiyonel, Max 8 |
| Chromebook | 16:9 | Opsiyonel, Max 8 |
| Wear OS | 1:1 | Opsiyonel, Max 8 |
| TV | 16:9, 1920x1080 | Opsiyonel, 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)
└───────────┘| Durum | Açıklama |
|---|---|
| Draft | Taslak — henüz gönderilmedi (not submitted yet) |
| In Review | İnceleniyor — Google ekibi kontrol ediyor |
| Approved | Onaylandı — yayınlanmaya hazır |
| Rejected | Reddedildi — sorunları düzelt ve tekrar gönder |
| Suspended | Askı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.
| Track | Amaç | Test kullanıcı sayısı |
|---|---|---|
| Internal testing | Hızlı dahili test (quick internal test) | Max 100 |
| Closed testing | Belirli kullanıcılarla beta (invite-only beta) | Sınırsız (unlimited) |
| Open testing | Herkese açık beta (public beta) | Sınırsız |
| Production | Canlı yayın (live release) | Tüm kullanıcılar |
# 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 toplamaTest 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.
// 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)
# 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 İşlevi | Açıklama |
|---|---|
| Code shrinking | Kullanılmayan kodu siler (removes unused code) |
| Obfuscation | Sınıf/metot adlarını kısaltır (shortens class/method names) |
| Optimization | Kodu optimize eder (optimizes bytecode) |
| Resource shrinking | Kullanı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
-keepkuralları eklemeyi unutmayın.
1.9 Google Play Politikaları ve Yaygın Red Nedenleri
İçerik Politikaları (Content Policies)
| Politika | Açıklama | Red Nedeni Örneği |
|---|---|---|
| Kısıtlı içerik | Şiddet, nefret söylemi, kumar yasak | Yaş doğrulama olmadan yetişkin içerik |
| Fikri mülkiyet | Telif hakkı ihlali yasak | Başka markanın logosunu/adını kullanmak |
| Yanıltıcı davranış | Aldatıcı uygulamalar yasak | Sahte işlevsellik iddiası |
| Cihaz ve ağ kötüye kullanımı | Malware, arka plan kötüye kullanım | Gereksiz 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 kullanabilirReklam Politikaları (Ad Policies)
| Kural | Açı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ı reklamlar | Kapatması zor, tam ekran kapatan reklamlar yasak |
| Reklam ID | AdID kullanımı beyan edilmeli |
Ödeme Politikaları (Payment Policies)
| Durum | Zorunlu 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)1.10 Google Play — Resmi Linkler (Official Links)
| Kaynak | Link |
|---|---|
| Play Console | https://play.google.com/console |
| Developer Policy Center | https://play.google.com/about/developer-content-policy |
| Data Safety | https://support.google.com/googleplay/android-developer/answer/10787469 |
| Launch Checklist | https://developer.android.com/distribute/best-practices/launch/launch-checklist |
| Play App Signing | https://developer.android.com/studio/publish/app-signing |
| Core Quality Guidelines | https://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.) | ❌ | ✅ | ✅ |
# 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ı gereklidir2.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 │
└──────────┘ └──────────┘ └──────────┘ └───────────┘# 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.plistExportOptions.plist
<?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)
| Sertifika | Kullanım | Geçerlilik |
|---|---|---|
| Development | Geliştirme ve cihaz testi | 1 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 Notification | Push 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ı |
|---|---|---|
| Development | Geliştirme testi | Max 100 cihaz |
| Ad Hoc | Beta dağıtım (beta distribution) | Max 100 cihaz |
| App Store | App Store yayınlama | Cihaz kısıtı yok (no device limit) |
| Enterprise | Dahili dağıtım (internal — $299 plan) | Sınırsız (unlimited) |
# 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)
| Cihaz | Boyut (Piksel) | Adet |
|---|---|---|
| iPhone 6.9" (15 Pro Max) | 1320 x 2868 | 1-10 |
| iPhone 6.7" (14 Pro Max) | 1290 x 2796 | 1-10 |
| iPhone 6.5" (11 Pro Max) | 1242 x 2688 | 1-10 |
| iPhone 5.5" (8 Plus) | 1242 x 2208 | 1-10 |
| iPad Pro 12.9" (6. nesil) | 2048 x 2732 | 1-10 |
| iPad Pro 12.9" (2. nesil) | 2048 x 2732 | 1-10 |
| Apple Watch | Cihaza göre değişir | 1-10 |
| Apple TV | 1920 x 1080 veya 3840 x 2160 | 1-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# 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üre | Durum |
|---|---|
| İ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 review | 24-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.
# 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// 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"
}
}
}
}# 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-submit2.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.
# 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-submitEAS Build ücretsiz mi?
| Plan | Aylık Build | Hız | Fiyat |
|---|---|---|---|
| Free | 30 build/ay | Kuyrukta bekleme | Ücretsiz |
| Production | 1000 build/ay | Öncelikli | $99/ay |
| Enterprise | Sınırsız | Adanmış sunucu | Özel fiyat |
Free plan çoğu küçük-orta proje için yeterlidir.
Yöntem 2: Codemagic (Flutter + React Native)
# 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: trueCodemagic ücretsiz mi?
| Plan | Dakika/ay | macOS | Fiyat |
|---|---|---|---|
| Free | 500 dk | M1 Mac Mini | Ücretsiz |
| Pay-as-you-go | Sınırsız | M1/M2 | $0.038/dk |
| Team | 3000 dk | M2 Pro | $299/ay |
Yöntem 3: GitHub Actions + macOS Runner
# .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)
| Servis | Fiyat | Kullanım |
|---|---|---|
| MacStadium | ~$79/ay | Adanmış Mac Mini |
| AWS EC2 Mac | ~$1.08/saat | On-demand Mac |
| MacinCloud | ~$20/ay | Paylaşı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öntem | Zorluk | Maliyet | Flutter | React Native | Expo |
|---|---|---|---|---|---|
| EAS Build | Çok kolay | Ücretsiz (30/ay) | ❌ | ✅ | ✅ |
| Codemagic | Kolay | Ücretsiz (500dk/ay) | ✅ | ✅ | ✅ |
| GitHub Actions | Orta | Ücretsiz (2000dk/ay) | ✅ | ✅ | ✅ |
| Mac kiralama | Zor | $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ın2.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ılamaz4.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)2.9 iOS — Resmi Linkler (Official Links)
| Kaynak | Link |
|---|---|
| App Store Connect | https://appstoreconnect.apple.com |
| App Store Review Guidelines | https://developer.apple.com/app-store/review/guidelines |
| Human Interface Guidelines | https://developer.apple.com/design/human-interface-guidelines |
| App Privacy | https://developer.apple.com/app-store/app-privacy-details |
| Developer Program | https://developer.apple.com/programs |
| Expedited Review | https://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)| Platform | Ad Limiti | Subtitle/Short Desc |
|---|---|---|
| App Store | 30 karakter | 30 karakter (subtitle) |
| Google Play | 30 karakter | 80 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ör | App Store | Google Play |
|---|---|---|
| Uygulama adı | ✅ Çok önemli (very important) | ✅ Çok önemli |
| Subtitle | ✅ Önemli | N/A |
| Keyword alanı | ✅ 100 karakter | N/A |
| Açıklama | ❌ İndexlenmez (not indexed) | ✅ İndexlenir (indexed) |
| Geliştirici adı | Minimal etki | ✅ İndexlenir |
| IAP adları | ✅ İndexlenir | Minimal 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 Boyutu | Format | Şeffaflık |
|---|---|---|---|
| App Store | 1024x1024 | PNG | Yok (no transparency) |
| Google Play | 512x512 | PNG (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 linkleriDerecelendirme 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)
| Platform | Desteklenen 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
| Kaynak | Link |
|---|---|
| App Store Product Page Optimization | https://developer.apple.com/app-store/product-page |
| Google Play Store Listing Experiments | https://support.google.com/googleplay/android-developer/answer/6227309 |
| Google Play ASO Guide | https://developer.android.com/distribute/best-practices/grow/store-listing |
4. Monetization — Gelir Modelleri (Revenue Models)
4.1 Gelir Modeli Türleri (Revenue Model Types)
| Model | Açıklama | Örnek Uygulamalar |
|---|---|---|
| Free (Ücretsiz) | Tamamen ücretsiz, reklam yok | Açık kaynak, kurumsal araçlar |
| Freemium | Temel özellikler ücretsiz, premium ücretli | Spotify, Canva, Evernote |
| Subscription (Abonelik) | Aylık/yıllık ücret | Netflix, Headspace, Notion |
| One-time Purchase (Tek seferlik) | Bir kez öde, her zaman kullan | Procreate, Dark Sky |
| In-App Purchase (IAP) | Uygulama içi satın alma — özellik/içerik | Oyunlar, fotoğraf filtreleri |
| Ad-supported (Reklam destekli) | Ücretsiz, reklam geliri | Oyunlar, haber uygulamaları |
| Hybrid (Karma) | Reklam + IAP + Abonelik | Duolingo (reklam + premium) |
4.2 Reklam Tipleri (Ad Types)
| Reklam Türü | Açıklama | eCPM (ortalama) | Kullanıcı Deneyimi |
|---|---|---|---|
| Banner | Ekran alt/üstünde sürekli gösterim | $0.5-2 | ⭐ Düşük etki (low impact) |
| Interstitial | Tam 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 Open | Uygulama 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 etkileyebilir4.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)
// 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)
// 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// 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)
| Platform | Standart Komisyon | Düşük Komisyon | Koşul |
|---|---|---|---|
| Apple App Store | %30 | %15 | Small Business Program ($1M altı yıllık gelir) |
| Google Play | %15 (ilk $1M) | %15 | İlk $1M otomatik (%30 sonrası) |
| Google Play Abonelik | %15 | %15 | Tüm abonelikler (all subscriptions) |
| Apple Abonelik (1. yıl) | %30 | %15 | SBP üyeleri |
| Apple Abonelik (2. yıl+) | %15 | %15 | Kullanı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 Model | Neden |
|---|---|---|
| Utility (araç) | Freemium / One-time | Kullanıcılar düzenli ödeme yapmak istemez |
| Sosyal medya | Free + Reklam | Büyük kullanıcı tabanı gerekli |
| Oyun (Casual) | Free + Reklam + IAP | Rewarded ads + satın alınabilir içerik |
| Oyun (Premium) | One-time | Yüksek kaliteli, bağımsız oyunlar |
| İçerik / Medya | Subscription | Sürekli güncellenen içerik |
| Eğitim | Freemium / Subscription | Temel ücretsiz, gelişmiş ücretli |
| Sağlık / Fitness | Subscription | Sürekli motivasyon ve içerik |
| Verimlilik (Productivity) | Freemium / Subscription | Temel özellikler ücretsiz, pro özellikler ücretli |
| B2B / SaaS | Subscription | İşletme bütçesi döngüsel |
| E-ticaret | Free + 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şama | Amaç | Kullanıcılar | Süre |
|---|---|---|---|
| Alpha | Erken geliştirme testi (early dev testing) | Geliştirici ekip | Sürekli (continuous) |
| Beta | Özellik testi, geri bildirim (feature test) | Seçili kullanıcılar / beta testers | 1-4 hafta |
| RC (Release Candidate) | Son kontrol, stabilite testi | QA ekibi + seçili kullanıcılar | 3-7 gün |
| Production | Canlı 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 │ │ │
└───────┘ └───────┘ └───────┘ └───────┘ └───────┘| Platform | Staged Rollout Desteği | Kontrol |
|---|---|---|
| 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 indirebilir5.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 │
└─────────┘ └──────────┘| Platform | Rollback | Hotfix 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öndermeli | Yeni build, expedited review talep et |
# 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ınla5.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// 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ı deneyim5.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)| Platform | Version | Build Number | Açıklama |
|---|---|---|---|
| Android | versionName | versionCode | versionCode her yüklemede artmalı (integer) |
| iOS | CFBundleShortVersionString | CFBundleVersion | Build number her yüklemede artmalı |
// 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
}
}<!-- 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 -->// Expo — app.json
{
"expo": {
"version": "2.1.0",
"ios": {
"buildNumber": "15"
},
"android": {
"versionCode": 15
}
}
}# 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.06. 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).
# Fastlane kurulumu (installation)
# macOS
brew install fastlane
# Ruby gem
gem install fastlane
# Proje dizininde başlat (initialize in project directory)
fastlane initiOS Fastfile
# 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
endAndroid Fastfile
# 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# 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 rollout6.2 EAS Build — Expo Otomasyon
# 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"// 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
# 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: true6.4 GitHub Actions — Mobil Workflow
Android Build + Deploy
# .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: completediOS Build + Deploy
# .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# 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 productionOTA 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)
| Özellik | Android (Google Play) | iOS (App Store) |
|---|---|---|
| Geliştirici hesabı | Google Play Console | Apple Developer Program |
| Kayıt ücreti | $25 tek seferlik (one-time) | $99/yıl (annual) |
| Build formatı | AAB (zorunlu / required) | IPA (via Xcode Archive) |
| İmzalama | Keystore + Play App Signing | Sertifika + Provisioning Profile |
| Test aracı | Internal/Closed/Open test tracks | TestFlight |
| İnceleme süresi | 1-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ğu | Play 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ği | API 21 (Android 5.0) önerilen | iOS 16+ önerilen |
| Dağıtım esnekliği | APK dağıtımı, alternatif mağazalar | Sadece App Store (Enterprise hariç) |
| A/B test | ✅ Store listing experiments | ✅ Product page optimization |
| Uygulama boyutu limiti | 150 MB AAB (+ asset packs) | 4 GB (cellular: 200 MB limit) |
8. İlgili Rehberler (Related Guides)
| Rehber | Açıklama |
|---|---|
| React Native Rehberi | React Native ile mobil uygulama geliştirme |
| Flutter Rehberi | Flutter ile cross-platform geliştirme |
| Docker Rehberi | CI/CD altyapısı için Docker |
| Figma Rehberi | Mobil UI tasarımı |