Kotlin Multiplatform'da paylaşılan iş mantığı Android tarafında sorunsuz çalışır; KMP iOS entegrasyonu ise ek bir kurulum disiplini ister çünkü Kotlin/Native önce bir framework üretir ve bu framework Xcode projesine ayrı bir adımda bağlanır: framework'ü Xcode projesine bağlamak, Swift interop tiplerini doğru okumak ve build zincirini kırmadan güncel tutmak kendi başına bir iş kalemidir. Kotlin 2.4.20 ile gelen Swift export genişlemeleri — sealed class'ların Swift enum'a dönüşmesi, çapraz dil kalıtımı ve otomatik Package.swift üretimi — bu tarafı belirgin şekilde sadeleştiriyor. Bu yazı, KMP'nin iOS tarafını Xcode entegrasyon yollarından Swift export'un yeni yeteneklerine kadar pratik adımlarla ele alıyor.
💡 Pro Tip: Swift export hâlâ Alpha aşamasında; production'da Objective-C header üretimini varsayılan bırakıp Swift export'u yeni modüllerde denemeye başlamak, API kırılmalarından etkilenme riskini düşürür.
İçindekiler
- KMP'de iOS Neden En Zor Taraf
- Yerel vs Uzak Kurulum
- Xcode Projesine Bağlama Yolları
- Otomatik Package.swift Üretimi (Kotlin 2.4.20)
- Kotlin 2.4.20 Swift Export Ekleri: Sealed → Swift Enum
- Sealed Tip Genişlediğinde Ne Olur
- Cross-Language Inheritance: Kotlin'de Kontrat, Swift'te Implementasyon
- Suspend ve Flow Köprüsü: Kısa Bir Hatırlatma
- Interop'ta Dikkat Edilmesi Gereken Tipler
- Neden Alpha Etiketi Önemli
- Derleme Zamanında Güvenlik: Hata Ayıklamanın İlk Katmanı
- Incremental Derleme ile Daha Hızlı İterasyon
- iOS Ekibine KMP'yi Kabul Ettirme
- Compose Multiplatform ile Ortak UI: Kısa Bir Bağlam
- SSS
- KMP modülü Xcode projesine nasıl bağlanır?
- Kotlin 2.4.20 Swift export'ta sealed class nasıl görünür?
- Kotlin/Swift interop'ta hangi tipler sorun çıkarır?
- KMP iOS tarafında debug ve crash sembolizasyonu nasıl yapılır?
- Doğrudan entegrasyon mu, CocoaPods mu tercih etmeliyim?
- Swift export production'a hazır mı?
- Sonuç
- Kaynaklar
KMP'de iOS Neden En Zor Taraf
Android tarafında Kotlin/JVM zaten native dil olduğu için paylaşılan modül doğrudan bağımlılık gibi davranır. iOS tarafında ise Kotlin/Native önce bir framework'e (XCFramework) derlenir, bu framework Xcode projesine ayrı bir adım olarak eklenir ve Swift'in tip sistemiyle Kotlin'in tip sisteminin kesiştiği noktada interop katmanı devreye girer. JetBrains'in resmi entegrasyon rehberine göre bu bağlama işlemi tek bir yol değil, projenin yapısına göre değişen birkaç seçenekten oluşuyor.
Yerel vs Uzak Kurulum
Yerel kurulumda framework aynı repo içinde derlenip doğrudan Xcode projesine eklenir; uzak kurulumda ise framework bir paket kayıt sistemi (ör. SwiftPM registry) üzerinden dağıtılır. Yerel kurulumda framework aynı repoda derlendiği için Kotlin derlemesi iOS build'inin bir parçası olur ve ortak kod değiştiğinde uygulama anında güncellenir.
Çok modüllü büyük ekiplerde ise durum tersine dönebilir: paylaşılan modül ayrı bir repo'da yaşar, ayrı bir sürüm numarasıyla yayınlanır ve iOS uygulaması bu framework'ü tıpkı üçüncü parti bir bağımlılık gibi tüketir. Bu model, framework'ün API yüzeyini daha disiplinli tutmayı zorunlu kılar çünkü her değişiklik artık "aynı PR içinde" değil, ayrı bir sürüm yükseltmesi olarak iOS tarafına yansır — sealed export'un derleme-zamanı uyarıları tam da bu noktada, sürüm yükseltmesi sırasında unutulan case'leri yakalayarak işe yarıyor.
Xcode Projesine Bağlama Yolları
Kotlin resmi dokümantasyonu iOS entegrasyonunu önce yerel ve uzak diye ikiye ayırıyor: yerel kurulumu metinde iki ana seçenek (doğrudan entegrasyon ve CocoaPods) olarak tarif edip üç yerel yol başlığı (doğrudan entegrasyon, yerel Swift paketiyle SwiftPM entegrasyonu, yerel podspec ile CocoaPods entegrasyonu) listeliyor; uzak kurulumda ise iki yol (XCFramework'lerle SwiftPM ve XCFramework'lerle CocoaPods) tanımlı. Aşağıdaki tablo bu üç yerel kurulum başlığını karşılaştırıyor. Kotlin Multiplatform IDE eklentisini kullanıyorsan doğrudan entegrasyon varsayılan olarak uygulanır.
Yöntem | Ne zaman uygun | Kurulum şekli | Swift export |
|---|---|---|---|
Doğrudan entegrasyon | KMP IDE eklentisiyle yeni proje, tek repo | Xcode Build Phases'e New Run Script Phase eklenir; script :shared:embedAndSignAppleFrameworkForXcode görevini çağırır | Çalışır |
CocoaPods | Proje zaten Pod bağımlılıkları kullanıyorsa | Yerel podspec üzerinden CocoaPods bağımlılığı olarak eklenir | Çalışmaz |
SwiftPM (yerel paket) | Framework'ü yerel bir Swift paketi gibi tüketmek isteyenler | Package.swift üzerinden local path bağımlılığı | Çalışmaz |
Doğrudan entegrasyonda bu Run Script fazı Compile Sources'tan önce konur, Build Settings'te User Script Sandboxing kapatılır. Bu son kolon ise kritik bir kısıtı taşıyor: resmi Swift export dokümantasyonunun "Current limitations" bölümü, Swift export'un yalnızca iOS framework'ünü Xcode projesine doğrudan entegrasyonla bağlayan projelerde çalıştığını belirtiyor. Swift export kullanmayı planlıyorsan entegrasyon yöntemini buna göre seçmen gerekiyor.
Otomatik Package.swift Üretimi (Kotlin 2.4.20)
Bu kolaylık dar ve net bir koşulda devreye giriyor: SwiftPM paketlerine bağımlı bir XCFramework export ederken. Resmi dokümantasyon, böyle bir XCFramework'ün doğru çözümlenebilmesi için ortaya çıkan SwiftPM paketini yayınlaman gerektiğini söylüyor; buna yardımcı olmak için assembleSharedXCFramework Gradle görevi artık XCFramework ile birlikte dağıtılacak bir Package.swift dosyası üretiyor. Yani özellik "SwiftPM ile dağıtım yapmak" için değil, SwiftPM bağımlılığı taşıyan bir XCFramework export etmek için.
1# XCFramework + otomatik Package.swift üretimi2./gradlew :shared:assembleSharedXCFrameworkÜretilen Package.swift, XCFramework'ün ZIP arşiviyle birlikte ayrı bir Git deposuna gönderilerek Swift paketi olarak yayınlanır; iOS projesi paketi bu depodan bağımlılık olarak çözümler.
Kotlin 2.4.20 Swift Export Ekleri: Sealed → Swift Enum
Kotlin 2.4.20'nin öne çıkan Swift export özelliği, sealed class/sealed interface hiyerarşilerinin artık Swift enum'a eşlenmesi. Bu, Xcode'da exhaustive switch ifadeleri yazabilmen ve tam otomatik tamamlama alabilmen anlamına geliyor. Her sealed tip için üretilen sealedType() metodu, doğrudan alt sınıflara karşılık gelen enum case'lerini döndürüyor.
1// Kotlin tarafı — paylaşılan modül2sealed class PaymentState {3 class Idle : PaymentState() {4 override fun toString(): String = "Idle"5 }6 7 data class Processing(val orderId: String) : PaymentState()8 data class Failed(val reason: String) : PaymentState()9}10 11fun currentPaymentState(): PaymentState = PaymentState.Processing("A-1042")1// Swift tarafı — export edilen enum ile exhaustive switch2let state = currentPaymentState()3let label = switch state.sealedType() {4case let .idle(type):5 "Bekliyor: \(type.value)"6case let .processing(type):7 "İşleniyor: \(type.value.orderId)"8case let .failed(type):9 "Hata: \(type.value.reason)"10}11print(label) // İşleniyor: A-1042Dikkat edilecek nokta, sealedType() dönüşündeki her case'in payload'ının bir sarmalayıcı olması: alt sınıf örneğine type.value üzerinden erişirsin, doğrudan type.orderId ile değil.
Yeni bir alt sınıf eklendiğinde Swift derleyicisi switch'in artık exhaustive olmadığını derleme zamanında uyarır; yani default case'e güvenmek yerine derleme-zamanı güvenliği elde edersin. Bu davranışın detayları Kotlin 2.4 Swift Export: KMP'de Obj-C Köprüsü Bitiyor mu? yazısında Objective-C köprüsüyle karşılaştırmalı olarak işlendi.
Sealed Tip Genişlediğinde Ne Olur
Var olan bir sealed hiyerarşiye yeni bir alt sınıf eklemek, Android tarafında Kotlin derleyicisinin zaten yakaladığı bir durum. Swift export bu güvenliği Xcode tarafına da taşıdığı için, iki platformda ayrı ayrı "unutulan case" arama derdi ortadan kalkıyor — bir geliştirici Kotlin tarafında yeni bir case eklediğinde, iOS ekibi bunu ilk build hatasında fark ediyor, App Store'a giden yolda değil.
Cross-Language Inheritance: Kotlin'de Kontrat, Swift'te Implementasyon
Kotlin 2.4.20, Swift export'a çapraz dil kalıtımı (cross-language inheritance) desteği getiriyor. Kalıp şu şekilde çalışıyor: kontratı Kotlin tarafında tanımlarsın, platforma özgü gerçekleştirimi Swift tarafında sağlarsın. Resmi dokümantasyonun şart koştuğu iki parça var: Kotlin tarafında bir arayüz ve Swift gerçekleştiriminin türeyeceği bir open taban sınıf. Dokümantasyondaki örnek, CryptoKit gibi yalnızca Apple platformlarında bulunan bir kütüphaneyi Kotlin arayüzü arkasına gizlemek için bu kalıbı kullanıyor.
1// Kotlin — arayüz, onu kabul eden fonksiyon ve open taban sınıf2interface CryptoProvider {3 fun hashMD5(input: String): String4}5 6fun processHash(provider: CryptoProvider, input: String): String =7 provider.hashMD5(input)8 9open class SwiftBase1// Swift — export edilen SwiftBase'den türeyip arayüzü gerçekleştir2import CryptoKit3 4final class IosCryptoProvider: SwiftBase, CryptoProvider {5 func hashMD5(input: String) -> String {6 guard let data = input.data(using: .utf8) else { return "failed" }7 return Insecure.MD5.hash(data: data).description8 }9}10 11let provider = IosCryptoProvider()12// Kotlin fonksiyonunu cagirir, o da Swift'teki hashMD5 metodunu geri cagirir13print(processHash(provider: provider, input: "Hello, world!"))Bu yaklaşımın avantajı, paylaşılan modülde platform-spesifik expect/actual bloklarına ihtiyaç duymadan, Swift tarafının kendi native API'lerini doğrudan Kotlin arayüzüne bağlayabilmesi.
Suspend ve Flow Köprüsü: Kısa Bir Hatırlatma
Kotlin coroutine'lerinin (suspend fonksiyonlar ve Flow) Swift'in async/AsyncSequence dünyasına nasıl köprülendiği, Swift export'un 2.4.0'daki temel taşlarından biri. Bu yazı KMP'nin iOS entegrasyon mekaniğine odaklandığı için detaya girmiyor; temel köprüleme mantığı Kotlin 2.4 Swift Export yazısında ele alındı — özetle suspend fonksiyonlar Swift tarafında async fonksiyon olarak, Flow ise AsyncSequence uyumlu bir tip olarak görünüyor. Bu makalede sealed export ve cross-language inheritance'a odaklanmamızın nedeni, bu ikisinin 2.4.20 ile gelen ve henüz yeterince belgelenmemiş yeni yetenekler olması; suspend/Flow köprüsü ise Swift export'un 2.4.0'da (14 Temmuz 2026) Alpha'ya terfi ederken kazandığı eşzamanlılık desteğinin parçası ve zaten belgeli.
Interop'ta Dikkat Edilmesi Gereken Tipler
Swift export, Kotlin 2.4.20 itibarıyla resmi olarak Alpha aşamasında; bu, API yüzeyinin ve tip eşlemelerinin sürümler arasında değişebileceği anlamına geliyor. Bu nedenle her yeni Kotlin sürümünde export edilen tiplerin davranışını gerçek bir Xcode projesinde doğrulamak, özellikle generic tipler ve karmaşık sealed hiyerarşiler için önemli. Kesin ve güncel sınırlamalar için resmi Swift export dokümantasyonunun "Current limitations" bölümüne bakmak, üretim kararı vermeden önce en güvenilir adım.
Neden Alpha Etiketi Önemli
Bir API Alpha etiketliyken minor sürüm geçişlerinde bile davranış değişebilir. Bu yüzden Swift export'a bağımlı framework'lerin sürüm yükseltmelerini, üretime almadan önce ayrı bir staging build'inde test etmek makul bir güvenlik önlemi.
Derleme Zamanında Güvenlik: Hata Ayıklamanın İlk Katmanı
KMP'de iOS tarafı hata ayıklamasının en ucuz katmanı, çalışma zamanına hiç gelmeyen hatalardır. Sealed hiyerarşilerin exhaustive switch'e dönüşmesi tam olarak bunu sağlıyor: yeni bir case eklendiğinde derleyici Swift tarafındaki eksik dalları anında işaretliyor, böylece "unutulan case" hatası App Store'a gitmeden önce yakalanıyor. Bu, klasik Objective-C köprüsünde NSObject alt sınıfları ve NS_ENUM ile elde edilmesi çok daha zor olan bir güvenlik katmanı.
Incremental Derleme ile Daha Hızlı İterasyon
Kotlin 2.4.20 ile klib artefaktlarının incremental derlemesi Beta aşamasına geçti; bu, native hedeflerde her küçük değişiklikte tüm modülü yeniden derlemek zorunda kalmadan daha hızlı bir geri bildirim döngüsü kurmanı sağlıyor.
1# gradle.properties — incremental native derlemeyi etkinleştir2kotlin.incremental.native=trueiOS Ekibine KMP'yi Kabul Ettirme
Bir iOS ekibinden sık duyulan itiraz, "bu benim kodum değil, ben sadece bir framework'ü tüketiyorum" cümlesi olabilir. Bu mesafeyi azaltmanın en etkili yolu, paylaşılan modülün Xcode içinde sıradan bir Swift Package gibi görünmesini sağlamak: otomatik üretilen Package.swift, exhaustive switch ile IDE'de tam otomatik tamamlama ve derleme zamanı hataları, iOS geliştiricisinin günlük iş akışını neredeyse hiç değiştirmiyor. Küçük başlamak — tek bir domain modelini veya ağ katmanını paylaşarak — ekibin güveni oturana kadar makul bir strateji.
- Pilot modül: Önce tek bir domain (ör. kimlik doğrulama durumu) paylaş, tüm uygulamayı değil.
- Görünürlük: Swift tarafında üretilen tipleri IDE'de gösterip "bu sıradan bir Swift enum" mesajını ver.
- Geri dönüş planı: Framework'ü kaldırmanın maliyetini baştan hesapla, ekibe şeffaf sun.
- Ortak sözlük: Kotlin ve Swift tarafındaki isimlendirmeyi (sealed tip adları, fonksiyon imzaları) tek bir doküman üzerinden senkron tut; export sonrası isim farklılıkları kod incelemesinde kafa karışıklığı yaratır.
Bu sürecin en kritik anı genelde ilk büyük sürüm yükseltmesi. Swift export Alpha statüsündeyken bir Kotlin minor sürümü API yüzeyini değiştirebilir; bu nedenle yükseltmeyi doğrudan main dalına değil, önce bir deneme dalında yapıp CI'da tam bir Xcode build'i almak, ekibin "KMP bizi sürpriz bir build hatasıyla durdurdu" algısını oluşturmasını engeller.
Compose Multiplatform ile Ortak UI: Kısa Bir Bağlam
Bu yazı KMP'nin iş mantığı/interop tarafına odaklanıyor; UI katmanını paylaşmak istersen Compose Multiplatform ayrı bir katman olarak devreye giriyor. Compose Multiplatform 1.12.0, 25 Ağustos 2026'da yayınlandı ve iOS tarafında metin seçim tutamaçlarının native görünüme uyarlanması ile metin alanlarına context menu'de "Select" öğesi eklenmesi gibi küçük ama gözle görülür iyileştirmeler getirdi. Compose Multiplatform'un en güncel Kotlin sürümüyle uyumlu çalıştığını ve 1.8.0'dan beri K2 derleyicisine tam geçtiğini belirtmek gerekir. Android + iOS production dağıtımının detayları Compose Multiplatform: Android + iOS Production Deployment 2026 yazısında; KMP'nin genel production hikâyesi için Kotlin Multiplatform 1.1 Stable: Production Case Study 2026 yazısına bakabilirsin.
Bu ayrımı netleştirmek önemli: Swift export ve sealed→enum eşlemesi, UI'dan bağımsız olarak yalnızca paylaşılan iş mantığı katmanında çalışır. Compose Multiplatform'u hiç kullanmadan, tamamen native SwiftUI ekranlarıyla da bu makaledeki interop tekniklerinin tamamından faydalanabilirsin — ikisi birbirine bağımlı değil, tamamlayıcı iki katman.
ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?
Okuyucu Ödülü
KMP'nin iOS tarafına geçmeden önce üzerinden geçmen gereken pratik bir kontrol listesi hazırladık; bu liste build zincirini kırmadan Swift export'a geçişi güvenli hale getirmek için düşünüldü.
SSS
KMP modülü Xcode projesine nasıl bağlanır?
Kotlin Multiplatform tarafı bir XCFramework üretir; bu framework assembleSharedXCFramework Gradle görevi ile derlenir ve Xcode projesine doğrudan entegrasyon, yerel podspec ile CocoaPods ya da yerel Swift paketiyle SwiftPM yollarından biriyle eklenir. Kotlin 2.4.20'den itibaren bu görev, SwiftPM paketlerine bağımlı bir XCFramework export ederken, XCFramework ile birlikte dağıtılacak bir Package.swift dosyasını da otomatik üretiyor.
Kotlin 2.4.20 Swift export'ta sealed class nasıl görünür?
Kotlin'deki sealed class/sealed interface hiyerarşisi, exhaustive switch ile kullanılabilen bir Swift enum'a dönüştürülür. Her sealed tip için üretilen sealedType() metodu, alt sınıflara karşılık gelen case'leri döner; yeni bir alt sınıf eklendiğinde Swift derleyicisi switch'in artık exhaustive olmadığını derleme zamanında bildirir.
Kotlin/Swift interop'ta hangi tipler sorun çıkarır?
Swift export Kotlin 2.4.20 itibarıyla Alpha statüsünde olduğu için tip eşlemelerinde sürümler arası davranış değişikliği görülebilir. Kesin ve güncel sınırlamalar resmi Swift export dokümantasyonunun "Current limitations" bölümünde tutuluyor; production kararı öncesi bu bölümü güncel Kotlin sürümüyle tekrar kontrol etmek gerekiyor.
KMP iOS tarafında debug ve crash sembolizasyonu nasıl yapılır?
Bu alanda 2.4.20'ye özgü doğrulanmış bir yenilik bulunmuyor; ama sealed hiyerarşilerin exhaustive switch'e dönüşmesi, birçok mantık hatasını çalışma zamanına hiç gelmeden derleme aşamasında yakalayarak dolaylı bir hata ayıklama katmanı sağlıyor. Bu, App Store'a gitmeden önce "unutulan case" türü hataların önüne geçiyor.
Doğrudan entegrasyon mu, CocoaPods mu tercih etmeliyim?
Proje zaten CocoaPods bağımlılıkları kullanıyorsa CocoaPods entegrasyonu ek bir araç zincirine gerek bırakmaz; yeni bir proje kuruyorsan ve Kotlin Multiplatform IDE eklentisini kullanıyorsan doğrudan entegrasyon varsayılan ve daha az sürtünmeli yoldur. Ama Swift export kullanmayı planlıyorsan seçim serbest değil: resmi dokümantasyon Swift export'un yalnızca doğrudan entegrasyon kullanan projelerde çalıştığını belirtiyor.
Swift export production'a hazır mı?
Resmi dokümantasyon Swift export'un Kotlin 2.4.20 itibarıyla Alpha aşamasında olduğunu belirtiyor; bu, API'nin production'da kullanılamayacağı anlamına gelmez ama sürüm yükseltmelerinin staging ortamında test edilmesini gerektiren bir olgunluk seviyesi olduğu anlamına gelir.
Sonuç
Kotlin 2.4.20, KMP'nin iOS tarafını üç cephede sadeleştirdi: otomatik Package.swift üretimiyle SwiftPM entegrasyonunu, sealed→enum export'uyla tip güvenliğini ve cross-language inheritance ile platforma özgü API'lere erişimi. Bunların hiçbiri Objective-C köprüsünün tamamen ortadan kalktığı anlamına gelmiyor — Swift export hâlâ Alpha — ama günlük geliştirme sürtünmesini gözle görülür şekilde azaltıyor. Ekibinle küçük bir pilot modülden başlayıp otomatik üretilen Package.swift'i CI zincirine erken dahil etmek, bu geçişi en az sürprizle yapmanın yolu.
Sealed export'un Objective-C köprüsüyle karşılaştırmalı detayları için Kotlin 2.4 Swift Export, genel production hikâyesi için Kotlin Multiplatform 1.1 Production Case Study, UI katmanını da paylaşmak istersen Compose Multiplatform Production Deployment yazılarına bakabilirsin. K2 derleyicisinin genel Kotlin ekosistemine etkisi için Kotlin 2.1: K2 Compiler + Context Parameters, cross-platform seçim kararı için ise Flutter vs SwiftUI: 3 Yıl + 60K LOC Production Karşılaştırması faydalı bir karşılaştırma sunuyor.
Kaynaklar
- Kotlin 2.4.20'de yeni neler var — Swift export, otomatik Package.swift ve incremental derleme detayları
- Kotlin sürüm takvimi — tooling release kadansı ve 2.5.0 planı
- KMP iOS entegrasyon genel bakış — doğrudan, CocoaPods ve SwiftPM yolları
- Swift export dokümantasyonu — Alpha statüsü ve sınırlamalar
- Compose Multiplatform uyumluluk ve sürümleme — Kotlin sürüm uyumu ve K2 geçişi
- Compose Multiplatform 1.12.0 sürüm notları — iOS metin seçim ve context menu düzeltmeleri
Etiketler
iOS Geliştirme Haberleri
Haftalık Swift tips, SwiftUI tricks ve iOS best practices. Spam yok, sadece değerli içerik.
Onay e-postasındaki bağlantıyı açıp “Aboneliğimi onayla” düğmesine bastığında aboneliğin başlar. Bültende açılma/tıklama istatistikleri tutulur; dilediğin an tek tıkla ayrılabilirsin. Gizlilik
