App Store'a Uygulama Yayınlama Süreci: Adım Adım Rehber
6 dk okuma

App Store'a uygulama yayınlamak, kod yazmaktan ayrı bir iştir: hesap, imzalama, mağaza kaydı, görseller, gizlilik beyanları, test dağıtımı ve inceleme. Adımların hiçbiri zor değil, ama sırası ve birbirine bağımlılığı bilinmediğinde günler kaybettirir. Bu rehber, Xcode'da çalışan bir uygulamanız olduğu noktadan mağazada yayında olduğu noktaya kadar olan yolu sırayla anlatıyor.
Ücretler, inceleme süreleri ve zorunlu ekran görüntüsü boyutları zaman içinde değişiyor. Bu yüzden burada rakam vermiyorum; güncel değerleri her zaman Apple'ın kendi sayfalarından ve App Store Connect'in o an gösterdiği alanlardan kontrol edin.
1. Apple Developer Program Üyeliği
Simülatörde ve kendi cihazınızda denemek için ücretsiz bir Apple hesabı yeter. Mağazada yayınlamak ve TestFlight kullanmak içinse yıllık ücretli Apple Developer Program üyeliği gerekir. Kayıt, Apple Developer uygulaması ya da web sitesi üzerinden yapılır ve kimlik doğrulama içerir.
İki tür üyelik var: bireysel ve kurumsal. Bireysel üyelikte mağazada satıcı adı olarak kendi adınız görünür. Kurumsal üyelikte şirket adı görünür, ama tüzel kişiliğinizi kanıtlamanız ve bir D-U-N-S numarası almanız gerekir; bu da süreci uzatır. Üyelik onayı anında gelmeyebilir, bu yüzden uygulama bitmeden başvurun.
2. Bundle ID ve İmzalama
Her uygulamanın ters alan adı biçiminde benzersiz bir bundle identifier'ı olur, örneğin com.sirketadi.uygulamaadi. Mağazaya ilk derlemeyi yükledikten sonra bu değeri değiştiremezsiniz, o yüzden baştan düzgün seçin.
Sertifika, App ID ve provisioning profile kavramları eskiden en çok vakit alan kısımdı. Bugün tek geliştirici için yapılacak şey şu: Xcode'da hedefi seçin, Signing & Capabilities sekmesinde "Automatically manage signing" kutusunu işaretleyin ve ekibinizi seçin. Xcode App ID'yi kaydeder, sertifikayı oluşturur ve profilleri kendisi yönetir. Elle imzalamaya ancak CI sunucusu ya da çok kişili ekiplerde ihtiyaç duyarsınız.
Aynı ekranda sürüm numaralarına da bakın. Version kullanıcıya görünen sürümdür (1.0.0), Build ise her yüklemede artması gereken iç numaradır. Aynı sürüm için aynı build numarasıyla ikinci kez yükleme yapamazsınız.
3. App Store Connect Kaydı
App Store Connect'te Apps bölümünden yeni uygulama oluşturun. İstenen bilgiler: platform, uygulama adı, birincil dil, bundle ID ve SKU. Uygulama adı mağaza genelinde benzersiz olmalı; istediğiniz ad alınmışsa kaydı oluşturamazsınız, yani adı erkenden ayırtmak mantıklı. SKU yalnızca sizin gördüğünüz bir iç koddur.
Ücretli uygulama ya da uygulama içi satın alma planlıyorsanız Business bölümünde ücretli uygulamalar sözleşmesini kabul etmeniz, banka ve vergi bilgilerini girmeniz gerekir. Ücretsiz bir uygulamada bu adım zorunlu değildir. Avrupa Birliği ülkelerinde dağıtım yapacaksanız, AB Dijital Hizmetler Yasası (DSA) gereği tacir olup olmadığınızı beyan etmeniz de isteniyor.
4. Mağaza Sayfası İçin Gerekenler
Sürüm sayfasında doldurmanız gereken alanlar şunlar:
- Ekran görüntüleri. Hangi cihaz boyutlarının zorunlu olduğu App Store Connect'te yazıyor ve zamanla değişiyor. Uygulama iPad'de de çalışıyorsa iPad görüntüleri de istenir. Görüntüler uygulamanın gerçek ekranlarını göstermeli.
- Açıklama, anahtar kelimeler, alt başlık, kategori.
- Destek URL'si. Zorunlu. Açılan, gerçek bir iletişim yolu sunan bir sayfa olmalı.
- Gizlilik politikası URL'si. Zorunlu. Herkese açık ve kalıcı bir adreste durmalı.
- Uygulama gizliliği beyanı. Mağazada "gizlilik etiketi" olarak görünen bölüm. Hangi veri türlerini topladığınızı, bunların kullanıcının kimliğine bağlanıp bağlanmadığını ve izleme amacıyla kullanılıp kullanılmadığını işaretlersiniz. Kullandığınız üçüncü taraf SDK'ların (analiz, reklam, kilitlenme raporu) topladığı veriler de sizin sorumluluğunuzdadır.
- Yaş derecelendirmesi. Bir anket doldurursunuz; sonuç otomatik hesaplanır. Kullanıcı içeriği ve sosyal özellikler dereceyi yükseltir.
- Şifreleme beyanı. Her yüklemede sorulmaması için
Info.plistiçineITSAppUsesNonExemptEncryptionanahtarını uygulamanıza uygun değerle ekleyebilirsiniz.
Bu maddelerin kendi uygulamamda ne kadar zaman aldığını LevelUpStudy'yi App Store'a çıkarma deneyimimde anlattım; özeti şu: bunları geliştirmenin sonuna değil başına yazın.
5. Arşivleme ve Yükleme
Xcode'da çalıştırma hedefi olarak bir simülatör değil Any iOS Device seçin, ardından Product > Archive. Arşiv bitince Organizer penceresi açılır. Distribute App > App Store Connect > Upload adımlarını izleyin. Xcode derlemeyi imzalar ve yükler.
Yükleme bittikten sonra derleme hemen görünmez; Apple tarafında bir işleme aşamasından geçer ve bittiğinde e-posta gelir. Bu aşamada eksik bir izin açıklaması ya da geçersiz bir ikon varsa, sorunu anlatan bir e-posta alırsınız ve derleme listeye hiç düşmeyebilir.
6. TestFlight
Derleme işlendiğinde TestFlight sekmesinde görünür. İki tür test kullanıcısı var:
- Dahili test kullanıcıları: App Store Connect ekibinizdeki kişiler. İnceleme beklemeden derlemeye erişirler.
- Harici test kullanıcıları: E-posta ya da herkese açık bağlantıyla davet edilir. İlk derleme kısa bir beta incelemesinden geçer.
TestFlight derlemeleri sınırlı bir süre sonra geçerliliğini yitirir. Asıl değeri şurada: uygulamayı gerçek cihazda, mağaza imzasıyla denersiniz. Bildirimler, satın alma akışı ve derin bağlantılar gibi konular simülatörde farklı davranabilir.
7. İncelemeye Gönderme
Sürüm sayfasında derlemeyi seçin ve App Review Information bölümünü doldurun: iletişim bilgileri, notlar ve uygulama giriş gerektiriyorsa çalışan bir demo hesabı. İnceleyen kişi giriş yapamazsa uygulamanın geri kalanına bakamaz ve gönderim reddedilir.
Yayın seçeneğini de burada belirlersiniz: onaydan sonra otomatik, sizin elle onayınızla ya da belirli bir tarihte. İlk sürümde elle yayınlamayı seçmek, duyuruyu kendi zamanlamanıza göre yapmanızı sağlar.
Sık Yapılan Hatalar: En Yaygın Ret Sebepleri
Kuralların tamamı App Review Guidelines sayfasında. Pratikte en sık karşılaşılanlar şunlar.
Hesap oluşturuluyor ama silinemiyor
Belirti: Ret mesajında hesap silme seçeneğinin bulunamadığı yazar. Hesap açılabilen her uygulama, hesabın uygulama içinden silinmesini başlatabilmelidir; "bize e-posta atın" yeterli değildir. Çözüm: Ayarlar ekranına görünür bir silme seçeneği koyun ve sunucu tarafında gerçekten silin.
import SwiftUI
struct DeleteAccountButton: View {
let deleteAccount: () async throws -> Void
@State private var isConfirming = false
@State private var errorMessage: String?
var body: some View {
Button("Hesabımı Sil", role: .destructive) {
isConfirming = true
}
.confirmationDialog(
"Hesabın ve tüm verilerin kalıcı olarak silinecek.",
isPresented: $isConfirming,
titleVisibility: .visible
) {
Button("Kalıcı Olarak Sil", role: .destructive) {
Task {
do {
try await deleteAccount()
} catch {
errorMessage = "Hesap silinemedi. Lütfen tekrar dene."
}
}
}
}
.alert("Hata", isPresented: .constant(errorMessage != nil)) {
Button("Tamam") { errorMessage = nil }
} message: {
Text(errorMessage ?? "")
}
}
}Sunucu tarafında bunun nasıl yapıldığını Firebase Auth ve hesap silme yazısında, Task ve async kullanımını ise async/await rehberinde bulabilirsiniz.
Eksik izin açıklaması
Belirti: Kamera, fotoğraf arşivi, konum ya da mikrofona eriştiğiniz anda uygulama çöker veya yükleme sonrası eksik "purpose string" uyarısı gelir. Çözüm: Kullandığınız her korumalı kaynak için Info.plist'e açıklama ekleyin. Metin, verinin ne için kullanıldığını söylemeli; "Kamera erişimi gerekli" gibi boş bir cümle de ret sebebidir.
<key>NSCameraUsageDescription</key>
<string>Profil fotoğrafı çekebilmen için kameraya erişiyoruz.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Galerinden profil fotoğrafı seçebilmen için fotoğraflarına erişiyoruz.</string>Bozuk bağlantılar ve yer tutucu içerik
Belirti: Ret mesajı uygulamanın eksik ya da tamamlanmamış olduğunu söyler. Sebep çoğu zaman açılmayan bir destek ya da gizlilik sayfası, "Lorem ipsum" metni, boş bir sekme, "yakında" yazan bir düğme ya da inceleme sırasında kapalı olan bir test sunucusudur. Çözüm: Göndermeden önce her bağlantıyı gerçek cihazda açın, bitmemiş özellikleri derlemeden çıkarın ve arka ucun inceleme boyunca ayakta olduğundan emin olun.
Çökme ve beyan uyuşmazlığı
İnceleme sırasındaki tek bir çökme ret için yeterlidir. Zorla açılan bir optional, en sık çökme sebeplerinden biridir; optionals ve guard let yazısındaki alışkanlıklar burada doğrudan işe yarar. İkinci büyük grup uyuşmazlıklardır: ekran görüntüleri uygulamayı yansıtmıyor, gizlilik beyanı uygulamanın gerçekte topladığı veriyle örtüşmüyor ya da üçüncü taraf bir sosyal giriş sunulurken kurallarda istenen eşdeğer gizlilik odaklı giriş seçeneği bulunmuyor.
Ret aldığınızda panik yapmayın. App Store Connect'teki mesaj bölümünden inceleme ekibine cevap yazabilir, gerekirse açıklama isteyebilir, düzeltip yeniden gönderebilirsiniz.
Onaydan Sonra
Onay geldiğinde, seçtiğiniz yayın seçeneğine göre uygulama ya kendiliğinden ya da siz yayınla dediğinizde mağazaya çıkar; tüm ülkelerde görünmesi biraz zaman alabilir. Bundan sonrası bakım işidir:
- Xcode Organizer ve App Store Connect üzerinden çökme raporlarını ve kullanım verilerini izleyin.
- Kullanıcı yorumlarına App Store Connect'ten cevap verin.
- Her güncelleme yeni bir sürüm numarası ve yeni bir inceleme demektir. Güncellemeleri kademeli olarak yayınlama seçeneği, bir hatanın herkese aynı anda ulaşmasını önler.
- Üyeliğinizi yenilemeyi unutmayın; üyelik sona erdiğinde uygulamalarınız mağazadan indirilemez hâle gelir.
Sık Sorulan Sorular
App Store'a uygulama yüklemek için Mac şart mı?
Evet, derlemeyi imzalayıp yüklemek için Xcode, Xcode için de macOS gerekir. Kendi Mac'iniz yoksa bulut tabanlı Mac hizmetleri ya da bir CI servisi kullanılabilir, ama hata ayıklama için gerçek bir Mac işleri çok kolaylaştırır.
İnceleme ne kadar sürer?
Sabit bir süre yok ve dönemden döneme değişiyor. Planınızı, ilk gönderimin reddedilip ikinci bir tur gerekebileceğini hesaba katarak yapın.
Ret alırsam uygulamam kalıcı olarak engellenir mi?
Hayır. Ret, o gönderimin düzeltilmesi gerektiği anlamına gelir. Sorunu giderip yeniden gönderirsiniz; kararın hatalı olduğunu düşünüyorsanız itiraz da edebilirsiniz.
Bireysel hesapla başlayıp sonra şirkete geçebilir miyim?
Apple, bireysel üyeliğin kuruma dönüştürülmesine ve uygulamaların hesaplar arasında aktarılmasına izin veriyor. Koşullar değişebildiği için başlamadan önce güncel yönergeleri okuyun.
İlgili Yazılar
SwiftUI ile İlk Uygulama: Adım Adım Başlangıç Rehberi
Xcode'da proje açmaktan simülatörde çalıştırmaya kadar SwiftUI ile ilk uygulama: App, View, VStack, @State, List ve TextField ile yapılacaklar listesi.
SwiftUI @State, @Binding ve @Observable: Veri Akışı Rehberi
SwiftUI'da @State, @Binding, @Observable, @Bindable ve @Environment ne zaman kullanılır? ObservableObject ile farkı, karar tablosu ve sık görülen hatalar.
Swift Struct ve Class Farkı: Değer ve Referans Tipleri
Swift'te struct ve class farkını çalıştırılabilir örneklerle öğrenin: kopyalama, mutating, let, ===, kalıtım, deinit ve hangisini ne zaman seçmeli.