← Nesim Apps

Mac Olmadan iPhone Uygulaması Yayınlamak: Kotlin Multiplatform, Bulut Mac ve TestFlight

Nesim Razon, bağımsız Android geliştiricisi · 2026-11-14

#Geliştirici notları#iOS

Windows'ta geliştirme yapıyorum ve Mac'im yok, ama küçük Android oyunum 2048'in App Store'da da olmasını istedim. Meğer masanda Mac olmasına gerek yokmuş; her derleme için birkaç dakikalığına bulutta bir Mac yeterli. İşte bir derlemeyi dizüstümden TestFlight'a ve bir gün içinde App Store incelemesine götüren hat ve yolda yediğim tuzaklar.

Projenin şekli

Oyun zaten Kotlin ve Jetpack Compose ile yazılmıştı, ben de onu Kotlin Multiplatform ve Compose Multiplatform'a taşıdım. Ortak bir modülde artık oyun kuralları, ekranlar, kayıtlı oyun, metinler ve yazı tipi duruyor. Android uygulaması bunun etrafında ince bir kabuk, küçük bir Swift uygulaması da iOS kabuğu.

Platformlar arasında farklı olan her şey tek bir küçük arayüzün arkasında: banner reklam, liderlik tablosu, puan isteme penceresi, paylaşma. Android bunu zaten kullandığı SDK'larla uyguluyor. iOS'ta Swift tarafı Google Mobile Ads SDK'sı ve Game Center ile uyguluyor. Bir ayrıntı daha: Android Gradle Plugin 9 ile Android uygulama eklentisi ve Kotlin Multiplatform eklentisi artık aynı modülde duramıyor, bu yüzden ortak kod kendi kütüphane modülünde.

Windows ne yapabilir, ne yapamaz

Kotlin, iOS kodunu Windows'ta derler. iOS simülatör derlemesi gibi görevler yerelde çalışır ve Kotlin hatalarını bildirir; yani ortak kodun ve iOS'a özel Kotlin'in çoğunu masamda kontrol edebildim. Windows'un yapamadığı şey iOS framework'ünü bağlamak, Swift uygulamasını derlemek ve imzalamak. Bu kısım macOS ister.

Pratik sonucu: Kotlin hatasını görmek için hiç Mac beklemiyorum, ama Swift hatası bir CI turuna mal oluyor, çünkü Swift tarafını elimde derleyici olmadan yazıyorum. Swift kodunu tam bu yüzden küçük tuttum.

Depoda Xcode proje dosyası yok

Xcode olmayınca elle düzenlenecek proje dosyası da yok; uygulamayı kısa bir YAML dosyasıyla anlatıyorum ve XcodeGen projeyi derleme makinesinde üretiyor. YAML'da paket kimliği, Info.plist değerleri, Game Center yetkisi, reklam için Swift paketleri ve Gradle'a ortak framework'ü derletip gömdüren bir ön derleme betiği var.

Bozuk bir YAML dosyası bir derleme başlangıcına mal olur. Benimki bir kez bozuldu: uzun bir listenin satır sonu kaybolmuştu ve iş saniyeler içinde düştü; artık her göndermeden önce dosyayı yerelde küçük bir betikle ayrıştırıyorum.

Bulut Mac

Derleme bir GitHub Actions macOS makinesinde çalışıyor. İş, kodu çeker, Java ve Gradle önbelleğini kurar, XcodeGen'i Homebrew ile yükler, projeyi üretir ve xcodebuild'i çalıştırır. Kullandığım makinede kurulu Xcode yeni bir 26.x sürümüydü; bu önemli, çünkü App Store Connect'e yükleme güncel bir SDK ister.

iOS dalına her gönderim hızlı, imzasız bir simülatör derlemesi çalıştırır. Mesajında testflight sözcüğü geçen bir commit ise onun yerine diğer işi çalıştırır: arşivler, imzalar, yükler. Böylece normal bir gönderim ucuz kalıyor ve bir derlemenin Apple'a ne zaman gideceğine ben karar veriyorum.

Mac olmadan imzalamak

Yine de bir Apple Developer üyeliği lazım, ama bir Mac'te anahtar zincirine gerek yok. App Store Connect'te bir API anahtarı oluşturup anahtar dosyasını, anahtar kimliğini ve yayıncı kimliğini depo gizli değişkenleri olarak saklıyorsun. xcodebuild bunları, hazırlık güncellemelerine izin veren bayrakla birlikte argüman olarak kabul ediyor; sertifikaları ve profilleri Apple bulutta oluşturup yönetiyor.

Dışa aktarma adımı, yöntemi app-store-connect, hedefi upload olan bir seçenek dosyası kullanır; yani arşivi dışa aktaran komut onu aynı anda TestFlight'a yükler.

Asıl tuzak anahtarın rolüydü. App Manager rolündeki anahtarla arşiv adımı geçti ama dışa aktarma bir bulut imzalama izin hatasıyla düştü. Admin rolünde yeni bir anahtar sorunu çözdü.

Ne kadara mal oluyor

Ücretsiz GitHub planında dahil kullanım dolar cinsinden ölçülür. Yazdığım sırada bir macOS dakikası bir Linux dakikasının yaklaşık on katı. Deneylerin ilk tam günü 54 macOS dakikası, yani dahil kredinin üç doların biraz üstünü kullandı; tek bir TestFlight turu yaklaşık altı dakika sürüyor.

İki alışkanlık maliyeti düşük tutuyor: simülatör derlemesini yalnızca yükleme istemediğimde çalıştırmak ve göndermeden önce dosyaları yerelde kontrol etmek. Dahil kredi biterse çalıştırmalar sadece durur; ödeme yöntemi bağlı olmayan bir planda sürpriz fatura çıkmaz.

Bilmeye değer küçük tuzaklar

Gerçek telefonda denemek

Derleme TestFlight üzerinden iOS 15.8 çalıştıran bir iPhone 7'de çalışıyor. Bunun için dağıtım hedefini iOS 15 yapmak yetti; eski bir telefon işe yarar bir düşük seviye test cihazı. Birkaç turdan sonra oyun Android'dekiyle aynı oynadı; reklamlar ve liderlik tablosu Swift tarafından çalışıyor.

Sık sorulan sorular

App Store'da uygulama yayınlamak için Mac gerekir mi?

Masanda gerekmez. Bir Mac derleme makinesi lazım ama GitHub Actions macOS makinesi gibi bir bulut makinesi bu işi görür. Yine de bir Apple Developer üyeliği gerekir.

Windows, iOS için Kotlin kodunu derleyebilir mi?

Kotlin kısmı için evet: iOS hedefleri Windows'ta derlenir. Framework'ü bağlamak, Swift uygulamasını derlemek ve imzalamak macOS ister.

Mac olmadan uygulama nasıl imzalanıyor?

Gizli değişken olarak saklanan bir App Store Connect API anahtarıyla. Bulut makinesindeki Xcode bunu bulutta yönetilen imzalama için kullanır ve doğrudan TestFlight'a yükler.

Bir bulut derlemesi ne kadar sürüyor?

Benim düzenimde bir TestFlight turu yaklaşık altı dakika sürdü; hiçbir şeyin önbellekte olmadığı ilk turda biraz daha fazla.

Diğer yazılar