Tüm Yazılar
Okuma Süresi
11 dk
Yayın Tarihi
2026-10-29
Kelime Sayısı
2.663kelime

Kahveni hazırla - bu içerikli bir makale!

KMP'de iOS: Kotlin 2.4.20 Swift Export ve Xcode Entegrasyonu

Özet

Kotlin 2.4.20'nin Swift export genişlemeleriyle KMP iOS entegrasyonu: Xcode'a bağlama yolları, sealed→enum dönüşümü, cross-language inheritance ve otomatik Package.swift üretimi.

  • Kotlin 2.4.20, Swift export'a sealed class → Swift enum eşlemesi getirerek Xcode'da exhaustive switch ve tam otomatik tamamlama sağlıyor.
  • SwiftPM paketlerine bağımlı bir XCFramework export ederken assembleSharedXCFramework Gradle görevi artık XCFramework ile birlikte dağıtılacak Package.swift dosyasını üretiyor.
  • Cross-language inheritance ile kontratı Kotlin'de tanımlayıp CryptoKit gibi platforma özgü API'lerin gerçekleştirimini Swift tarafında sağlayabilirsin.
  • Swift export hâlâ Alpha statüsünde; sürüm yükseltmelerini staging'de test etmek ve resmi 'Current limitations' bölümünü takip etmek üretimde güvenlik sağlıyor.
KMP'de iOS: Kotlin 2.4.20 Swift Export ve Xcode Entegrasyonu

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

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.

bash
1# XCFramework + otomatik Package.swift üretimi
2./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.

kotlin
1// Kotlin tarafı — paylaşılan modül
2sealed 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")
swift
1// Swift tarafı — export edilen enum ile exhaustive switch
2let 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-1042

Dikkat 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.

kotlin
1// Kotlin — arayüz, onu kabul eden fonksiyon ve open taban sınıf
2interface CryptoProvider {
3 fun hashMD5(input: String): String
4}
5 
6fun processHash(provider: CryptoProvider, input: String): String =
7 provider.hashMD5(input)
8 
9open class SwiftBase
swift
1// Swift — export edilen SwiftBase'den türeyip arayüzü gerçekleştir
2import CryptoKit
3 
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).description
8 }
9}
10 
11let provider = IosCryptoProvider()
12// Kotlin fonksiyonunu cagirir, o da Swift'teki hashMD5 metodunu geri cagirir
13print(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.

properties
1# gradle.properties — incremental native derlemeyi etkinleştir
2kotlin.incremental.native=true

iOS 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

Etiketler

#Kotlin Multiplatform#Swift Export#Xcode#iOS Interop#Kotlin 2.4.20#Cross-Platform
Muhittin Çamdalı

Muhittin Çamdalı

Senior Mobile Engineer

12+ yıllık deneyime sahip Senior Mobile Engineer. iOS, Flutter ve React Native ile mobil ürünler geliştiriyorum; full-stack ve AI-native çalışıyorum.

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

Paylaş

İlgili İçerik