Tüm Yazılar
Okuma Süresi
15 dk
Yayın Tarihi
2026-04-18
Kelime Sayısı
2.661kelime

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

Compose Multiplatform: Android + iOS Production Rehberi 2026

Özet

Compose Multiplatform stable, iOS native performance, shared UI components, Kotlin/Native memory management — production deployment için mimari kararlar ve beklenen mertebeler.

  • Compose Multiplatform 1.6+ iOS'ta stable; Metal renderer ile GPU acceleration sağlanıyor.
  • Yeni concurrent GC stop-the-world süresini 10ms altına indirdi (önceki 50-100ms idi).
  • Gerçekçi shared UI hedefi %70-80 bandı; bu bantta geliştirme süresi belirgin biçimde düşüyor.
  • iOS cold start 780ms bandı, native SwiftUI'ye göre ~%12 yavaş; memory kullanımı ~%22 fazla.
Compose Multiplatform: Android + iOS Production Rehberi 2026

Kotlin ekosistemi 2026 yılında mobile cross-platform geliştirme alanında çok önemli bir dönüşüm noktasına ulaştı. JetBrains'in Compose Multiplatform (CMP) framework'ü artık iOS platformunda da stable statüsüne kavuşmuş durumda ve production uygulamalarında kullanılabilir hale geldi. Bu gelişme, Android geliştiricilerinin zaten aşina olduğu Jetpack Compose API'sini iOS'a taşıyarak gerçek anlamda shared UI layer imkânı sunuyor.

Bu blog yazısında, bir production uygulamasında Compose Multiplatform 1.6+ kullanımının tüm yönlerini ele alıyoruz: mimari kararlar, performance tuning, iOS'a özgü zorluklar ve beklenen sonuçlar. Yazıdaki sayılar tek bir projenin ölçümü değil; bu mimaride raporlanan referans mertebeler. Kotlin/Native GC iyileştirmelerinden SwiftUI interop'a, Decompose navigation'dan design system paylaşımına kadar her konuyu derinlemesine inceleyeceğiz.

Pro Tip: Compose Multiplatform'a geçiş yapmadan önce expect/actual mekanizmasını sadece platform-specific business logic için değil, UI katmanında da stratejik biçimde kullanmayı planlayın. Her şeyi shared hale getirmeye çalışmak yerine, %70-80 oranında shared UI hedeflemek daha sürdürülebilir bir mimari sağlar.

İçindekiler

  • Compose Multiplatform 1.6+ Yenilikleri
  • UI Katmanı Paylaşım Stratejisi
  • expect/actual ile Platform-Specific UI
  • Kotlin/Native GC ve Memory Management
  • iOS Bridge Overhead ve Optimizasyon
  • SwiftUI Interop: ComposeUIViewController
  • Material 3'ün iOS'ta Cupertino Teması
  • Navigation: Decompose vs Voyager Karşılaştırması
  • Image Loading: Coil-KMP Entegrasyonu
  • Custom Gesture Handling
  • Performance Tuning: Lazy Lists
  • Hot Reload Workflow
  • Design System ve Token Paylaşımı
  • Screenshot Testing Stratejisi
  • Production Sonuçları ve Metrikler

Compose Multiplatform 1.6+ Yenilikleri

Compose Multiplatform 1.6 sürümüyle birlikte iOS desteği artık beta'dan çıkıp stable statüsüne ulaştı. Bu sürümün getirdiği en önemli yenilikler şunlar:

iOS Native Performance İyileştirmeleri: Metal renderer doğrudan kullanılarak GPU acceleration sağlandı. Önceki sürümlerde yaşanan frame drop problemleri büyük ölçüde çözüldü. Özellikle animasyon yoğun ekranlarda Android ile iOS arasındaki performans farkı %5'in altına indi.

Kotlin/Native GC Yeniden Yazımı: Yeni concurrent garbage collector, stop-the-world pause sürelerini 10ms'nin altına indirdi. Bu gelişme, smooth scrolling ve animasyon için kritik öneme sahip. Önceki GC implementasyonunda UI thread'i bloke eden 50-100ms'lik duraklama süreleri yaşanıyordu.

Text Rendering İyileştirmeleri: iOS'ta font rendering artık platform native text engine'i kullanıyor. CupertinoFont ailesi ile SF Pro ve SF Mono fontları doğrudan kullanılabilir hale geldi.

Accessibility Geliştirmeleri: VoiceOver entegrasyonu production-ready seviyeye ulaştı. Compose Semantics API'si iOS UIAccessibility framework'üne tam olarak map ediliyor.


UI Katmanı Paylaşım Stratejisi

Production uygulamasında ideal UI paylaşım oranını bulmak kritik bir mimari karar. Saha raporlarının ortak noktası şu: her şeyi shared yapmaya çalışmak yerine, platform-specific UX'e saygı göstermek daha iyi sonuç veriyor.

Önerilen Katman Yapısı:

kotlin
1// Shared module (commonMain)
2// - Business logic: %100
3// - ViewModels / Presenters: %100
4// - Repository layer: %100
5// - UI component'ları: %70-80
6// - Navigation graph: %80
7// - Platform-specific UI: %20-30 (expect/actual)
8 
9// Proje yapısı
10composeApp/
11 src/
12 commonMain/
13 kotlin/
14 ui/
15 components/ // Shared components
16 screens/ // Shared screens
17 theme/ // Design system tokens
18 domain/ // Business logic
19 data/ // Repository
20 androidMain/
21 kotlin/
22 ui/
23 platform/ // Android-specific UI
24 iosMain/
25 kotlin/
26 ui/
27 platform/ // iOS-specific UI

Bu yapıda shared kod oranı %75-80 bandına çıkabilir. Android ve iOS'a özgü kod ise yalnızca gerçekten platform-specific olan bölümler için ayrılır: permission handling, biometric authentication, platform-native pickers ve deep link handling.


expect/actual ile Platform-Specific UI

Compose Multiplatform'un en güçlü özelliklerinden biri expect/actual mekanizması. Bu mekanizma sadece business logic için değil, UI katmanında da kullanılabilir.

DatePicker Örneği:

kotlin
1// commonMain - Shared interface
2expect class PlatformDatePicker {
3 @Composable
4 fun Show(
5 selectedDate: Long?,
6 onDateSelected: (Long) -> Unit,
7 onDismiss: () -> Unit
8 )
9}
10 
11// androidMain - Material 3 DatePickerDialog
12actual class PlatformDatePicker {
13 @Composable
14 actual fun Show(
15 selectedDate: Long?,
16 onDateSelected: (Long) -> Unit,
17 onDismiss: () -> Unit
18 ) {
19 val datePickerState = rememberDatePickerState(
20 initialSelectedDateMillis = selectedDate
21 )
22 DatePickerDialog(
23 onDismissRequest = onDismiss,
24 confirmButton = {
25 TextButton(onClick = {
26 datePickerState.selectedDateMillis?.let(onDateSelected)
27 }) { Text("Tamam") }
28 }
29 ) {
30 DatePicker(state = datePickerState)
31 }
32 }
33}
34 
35// iosMain - UIDatePicker via UIKitView
36actual class PlatformDatePicker {
37 @Composable
38 actual fun Show(
39 selectedDate: Long?,
40 onDateSelected: (Long) -> Unit,
41 onDismiss: () -> Unit
42 ) {
43 UIKitView(
44 factory = {
45 UIDatePicker().apply {
46 datePickerMode = UIDatePickerModeDate
47 preferredDatePickerStyle = UIDatePickerStyleInline
48 addTarget(
49 this,
50 action = sel("dateChanged:"),
51 forControlEvents = UIControlEventValueChanged
52 )
53 }
54 },
55 modifier = Modifier.fillMaxWidth().height(300.dp)
56 )
57 }
58}

Bu pattern sayesinde her platform kullanıcılarına alışık oldukları native date picker deneyimi sunarken, business logic tamamen shared kalıyor.


Kotlin/Native GC ve Memory Management

iOS'ta Kotlin/Native çalışırken memory management farklı kurallara tabi. Yeni GC ile birlikte çoğu problem otomatik olarak çözülmüş olsa da bazı pattern'lere dikkat etmek gerekiyor.

Circular Reference Tuzakları:

kotlin
1// YANLIŞ - Circular reference (iOS'ta leak yaratabilir)
2class ViewModel {
3 var callback: (() -> Unit)? = null
4 
5 fun setup() {
6 callback = {
7 this.process() // 'this' capture circular ref yaratıyor
8 }
9 }
10}
11 
12// DOĞRU - WeakReference kullanımı
13class ViewModel {
14 var callback: (() -> Unit)? = null
15 
16 fun setup() {
17 val weakRef = WeakReference(this)
18 callback = {
19 weakRef.get()?.process()
20 }
21 }
22}

Coroutine Scope Yönetimi:

iOS'ta coroutine scope'ları özellikle dikkatli yönetilmeli. Compose'un rememberCoroutineScope() kullanımı Android'dekiyle aynı şekilde çalışıyor ve lifecycle'a bağlı olarak otomatik iptal ediliyor. Ancak ViewModel'larda viewModelScope yerine özel scope yönetimi gerekiyor:

kotlin
1// commonMain
2class SharedViewModel : ViewModel() {
3 // KMP-uyumlu scope
4 private val scope = MainScope() + SupervisorJob()
5 
6 override fun onCleared() {
7 scope.cancel()
8 super.onCleared()
9 }
10 
11 fun loadData() {
12 scope.launch {
13 try {
14 val result = repository.fetchData()
15 _uiState.update { it.copy(data = result) }
16 } catch (e: CancellationException) {
17 throw e // Her zaman rethrow et!
18 } catch (e: Exception) {
19 _uiState.update { it.copy(error = e.message) }
20 }
21 }
22 }
23}

iOS Bridge Overhead ve Optimizasyon

Kotlin/Native ile iOS native API'leri arasındaki her geçiş bir overhead maliyeti taşıyor. Bu overhead'i minimize etmenin yolları:

Batch Native Calls: Native API'lere tek tek erişmek yerine batch işlemler yapın.

UI Thread Kuralları: iOS UIKit işlemleri mutlaka main thread'de yapılmalı. DispatchQueue.main yerine Kotlin coroutines ile Dispatchers.Main kullanın.

Object Frozen Pattern: iOS'ta thread'ler arası paylaşılan objeler immutable olmalı. @Immutable ve data class kullanımı bu problemi çözüyor:

kotlin
1@Immutable
2data class UserProfile(
3 val id: String,
4 val name: String,
5 val avatarUrl: String?,
6 val preferences: UserPreferences
7)
8 
9@Immutable
10data class UserPreferences(
11 val theme: AppTheme,
12 val language: String,
13 val notificationsEnabled: Boolean
14)

SwiftUI Interop: ComposeUIViewController

Mevcut SwiftUI projesine Compose UI eklemek için ComposeUIViewController kullanılıyor. Bu interop katmanı bidirectional iletişimi destekliyor.

SwiftUI'dan Compose View Kullanımı:

Kotlin tarafında:

kotlin
1// iosMain
2fun MainViewController(): UIViewController =
3 ComposeUIViewController {
4 App()
5 }
6 
7// Parametre geçişi için
8fun ProfileViewController(userId: String): UIViewController =
9 ComposeUIViewController {
10 ProfileScreen(userId = userId)
11 }

Swift tarafında:

swift
1// SwiftUI içinde Compose view
2struct ComposeProfileView: UIViewControllerRepresentable {
3 let userId: String
4 
5 func makeUIViewController(context: Context) -> UIViewController {
6 return ProfileViewControllerCompanion().create(userId: userId)
7 }
8 
9 func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
10 // State updates buradan yapılır
11 }
12}
13 
14// SwiftUI View içinde kullanım
15struct ContentView: View {
16 var body: some View {
17 ComposeProfileView(userId: "user-123")
18 .ignoresSafeArea()
19 }
20}

Bu pattern, hybrid migration için ideal. Mevcut SwiftUI kodunuzu koruyarak Compose ekranlarını kademeli olarak entegre edebilirsiniz.


Material 3'ün iOS'ta Cupertino Teması

Material 3'ü iOS'ta doğrudan kullanmak, kullanıcıların alışık olmadığı bir görünüm ortaya çıkarabilir. JetBrains'in cupertino-adaptive kütüphanesi bu sorunu çözüyor.

Adaptive Theme Kurulumu:

kotlin
1// commonMain
2@Composable
3fun AppTheme(content: @Composable () -> Unit) {
4 val platformTheme = rememberAdaptiveTheme(
5 material = MaterialTheme(
6 colorScheme = dynamicLightColorScheme(), // Android Dynamic Color
7 typography = AppTypography
8 ),
9 cupertino = CupertinoTheme(
10 colorScheme = CupertinoLightColorScheme,
11 typography = CupertinoTypography.default
12 )
13 )
14 
15 AdaptiveTheme(
16 theme = platformTheme,
17 content = content
18 )
19}
20 
21// Adaptive component kullanımı
22@Composable
23fun AdaptiveButton(
24 text: String,
25 onClick: () -> Unit
26) {
27 AdaptiveWidget(
28 material = {
29 FilledTonalButton(onClick = onClick) {
30 Text(text)
31 }
32 },
33 cupertino = {
34 CupertinoButton(onClick = onClick) {
35 Text(text)
36 }
37 }
38 )
39}

Bu yaklaşım sayesinde Android'de Material You, iOS'ta native Cupertino görünümü elde ediliyor. Her iki platform kullanıcısı da alışık oldukları UX'i yaşıyor.


CMP için iki popüler navigation çözümü mevcut: Decompose ve Voyager. Her ikisinin production uygulamasındaki artı ve eksileri:

Decompose:

  • Component tabanlı mimari, deep link desteği güçlü
  • Back stack management iOS ve Android'de tutarlı
  • Lifecycle-aware component'lar
  • Öğrenme eğrisi dik, boilerplate fazla
  • Complex navigation graph için ideal

Voyager:

  • Compose-idiomatic API, hızlı başlangıç
  • Tab navigation ve bottom sheet desteği built-in
  • Daha az boilerplate
  • Deep link desteği Decompose kadar güçlü değil
  • Basit-orta complexity için ideal

Deep linking ve karmaşık navigation graph gereksinimi olan projelerde Decompose öne çıkıyor:

kotlin
1// Decompose ile navigation
2interface RootComponent {
3 val stack: Value<ChildStack<Config, Child>>
4 
5 sealed class Config : Parcelable {
6 @Parcelize data object Home : Config()
7 @Parcelize data class Profile(val userId: String) : Config()
8 @Parcelize data class Article(val articleId: String) : Config()
9 }
10 
11 sealed class Child {
12 class Home(val component: HomeComponent) : Child()
13 class Profile(val component: ProfileComponent) : Child()
14 class Article(val component: ArticleComponent) : Child()
15 }
16}
17 
18class RootComponentImpl(
19 componentContext: ComponentContext
20) : RootComponent, ComponentContext by componentContext {
21 
22 private val navigation = StackNavigation<RootComponent.Config>()
23 
24 override val stack: Value<ChildStack<RootComponent.Config, RootComponent.Child>> =
25 childStack(
26 source = navigation,
27 serializer = RootComponent.Config.serializer(),
28 initialConfiguration = RootComponent.Config.Home,
29 childFactory = ::createChild
30 )
31 
32 private fun createChild(
33 config: RootComponent.Config,
34 context: ComponentContext
35 ) = when (config) {
36 is RootComponent.Config.Home ->
37 RootComponent.Child.Home(HomeComponentImpl(context))
38 is RootComponent.Config.Profile ->
39 RootComponent.Child.Profile(ProfileComponentImpl(context, config.userId))
40 is RootComponent.Config.Article ->
41 RootComponent.Child.Article(ArticleComponentImpl(context, config.articleId))
42 }
43}

Image Loading: Coil-KMP Entegrasyonu

Coil 3.x artık KMP desteğiyle geliyor ve hem Android hem de iOS'ta çalışıyor. Önceki sürümlerde iOS için ayrı kütüphane gerekirken, artık tek API ile her iki platform destekleniyor.

kotlin
1// commonMain - Coil 3.x KMP
2@Composable
3fun NetworkImage(
4 url: String,
5 contentDescription: String?,
6 modifier: Modifier = Modifier,
7 placeholder: @Composable (() -> Unit)? = null
8) {
9 val imageLoader = LocalImageLoader.current
10 
11 AsyncImage(
12 model = ImageRequest.Builder(LocalPlatformContext.current)
13 .data(url)
14 .crossfade(300)
15 .memoryCachePolicy(CachePolicy.ENABLED)
16 .diskCachePolicy(CachePolicy.ENABLED)
17 .build(),
18 contentDescription = contentDescription,
19 imageLoader = imageLoader,
20 contentScale = ContentScale.Crop,
21 modifier = modifier,
22 placeholder = placeholder?.let { { it() } }
23 )
24}
25 
26// Platform-specific ImageLoader setup
27// androidMain
28actual fun createImageLoader(context: PlatformContext): ImageLoader =
29 ImageLoader.Builder(context)
30 .memoryCache {
31 MemoryCache.Builder()
32 .maxSizePercent(context, 0.25)
33 .build()
34 }
35 .diskCache {
36 DiskCache.Builder()
37 .directory(context.cacheDir.resolve("image_cache"))
38 .maxSizePercent(0.02)
39 .build()
40 }
41 .build()
42 
43// iosMain
44actual fun createImageLoader(context: PlatformContext): ImageLoader =
45 ImageLoader.Builder(context)
46 .memoryCache {
47 MemoryCache.Builder()
48 .maxSizePercent(context, 0.25)
49 .build()
50 }
51 .build() // iOS disk cache NSURLCache ile yönetiliyor

Performance Tuning: Lazy Lists

iOS'ta Compose lazy list performansı, doğru yapılandırma yapılmadığında Android'e göre daha kötü çıkabiliyor. Temel optimizasyonlar:

Key Kullanımı Zorunlu: Her list item'a benzersiz key atamak recomposition'ı minimuma indirgeyerek scroll performansını ciddi ölçüde artırıyor.

Item Type Ayrımı: Farklı item tiplerinde contentType parametresi View recycling'i optimize ediyor.

kotlin
1@Composable
2fun OptimizedFeedList(
3 items: List<FeedItem>,
4 modifier: Modifier = Modifier
5) {
6 LazyColumn(
7 modifier = modifier,
8 // iOS'ta fling davranışını smooth yapmak için
9 flingBehavior = ScrollableDefaults.flingBehavior(),
10 contentPadding = PaddingValues(vertical = 8.dp)
11 ) {
12 items(
13 items = items,
14 key = { item -> item.id }, // ZORUNLU
15 contentType = { item -> // Recycling optimizasyonu
16 when (item) {
17 is FeedItem.ArticleCard -> "article"
18 is FeedItem.ImageCard -> "image"
19 is FeedItem.VideoCard -> "video"
20 is FeedItem.AdCard -> "ad"
21 }
22 }
23 ) { item ->
24 // Stable lambda - her recomposition'da yeni lambda yaratma
25 val onItemClick = remember(item.id) {
26 { viewModel.onItemClick(item.id) }
27 }
28 
29 when (item) {
30 is FeedItem.ArticleCard -> ArticleCardItem(item, onItemClick)
31 is FeedItem.ImageCard -> ImageCardItem(item, onItemClick)
32 is FeedItem.VideoCard -> VideoCardItem(item, onItemClick)
33 is FeedItem.AdCard -> AdCardItem(item, onItemClick)
34 }
35 }
36 }
37}

Hot Reload Workflow

Compose Multiplatform ile hot reload, Android'deki deneyime yakın hale geldi. iOS Simulator üzerinde çalışırken Kotlin kodu değiştirildiğinde, Compose preview ve simulator otomatik güncelleniyor.

Kurulum Gereksinimleri:

  • Xcode 15.3+ ve iOS Simulator
  • Android Studio Hedgehog+ veya IntelliJ IDEA 2024.1+
  • Kotlin 2.0.0+
  • CMP 1.6+

Workflow:

  1. iOS Simulator'de uygulamayı başlatın
  2. Kotlin kaynak dosyasını değiştirin
  3. Kaydet (Cmd+S) - otomatik hot reload tetikleniyor
  4. Simulator ~2-3 saniyede güncelleniyor

Hot reload, business logic değişikliklerini desteklemiyor. Sadece Composable UI değişiklikleri hot reload ile uygulanabiliyor. ViewModel veya Repository değişikliklerinde tam yeniden derleme gerekiyor.


Design System ve Token Paylaşımı

Production uygulamasında design tokens'ın hem Android hem iOS arasında paylaşılması tutarlı bir görünüm sağlıyor.

kotlin
1// commonMain - Design tokens
2object AppColors {
3 val Primary = Color(0xFF6750A4)
4 val PrimaryVariant = Color(0xFF7C63B4)
5 val Secondary = Color(0xFF625B71)
6 val Background = Color(0xFFFFFBFE)
7 val Surface = Color(0xFFFFFBFE)
8 val Error = Color(0xFFB3261E)
9 
10 // Semantic colors
11 val Success = Color(0xFF34A853)
12 val Warning = Color(0xFFFBBC04)
13 val Info = Color(0xFF4285F4)
14}
15 
16object AppSpacing {
17 val xs = 4.dp
18 val sm = 8.dp
19 val md = 16.dp
20 val lg = 24.dp
21 val xl = 32.dp
22 val xxl = 48.dp
23}
24 
25object AppTypography {
26 val displayLarge = TextStyle(
27 fontFamily = FontFamily.Default,
28 fontWeight = FontWeight.W400,
29 fontSize = 57.sp,
30 lineHeight = 64.sp,
31 letterSpacing = (-0.25).sp
32 )
33 
34 val headlineMedium = TextStyle(
35 fontFamily = FontFamily.Default,
36 fontWeight = FontWeight.W400,
37 fontSize = 28.sp,
38 lineHeight = 36.sp
39 )
40 
41 val bodyLarge = TextStyle(
42 fontFamily = FontFamily.Default,
43 fontWeight = FontWeight.W400,
44 fontSize = 16.sp,
45 lineHeight = 24.sp,
46 letterSpacing = 0.5.sp
47 )
48}

Bu token sistemi Figma Variables ile senkronize edilebilir. Figma'dan JSON export edilerek Kotlin kod generator'ı ile otomatik token sınıfları üretmek mümkün.


Screenshot Testing Stratejisi

Compose Multiplatform'da screenshot testing hem Android hem de iOS için ayrı ayrı yapılmalı. Paparazzi (Android) ve iOS Snapshot Testing kütüphaneleri kullanılıyor.

kotlin
1// Android screenshot test (Paparazzi)
2@RunWith(Parameterized::class)
3class ProfileScreenshotTest(
4 private val theme: TestTheme
5) {
6 
7 @get:Rule
8 val paparazzi = Paparazzi(
9 deviceConfig = DeviceConfig.PIXEL_6,
10 theme = "android:Theme.Material.Light.NoActionBar"
11 )
12 
13 @Test
14 fun profileScreen_loadedState() {
15 paparazzi.snapshot {
16 AppTheme(darkTheme = theme == TestTheme.DARK) {
17 ProfileScreen(
18 state = ProfileUiState.Success(
19 user = mockUser,
20 posts = mockPosts
21 )
22 )
23 }
24 }
25 }
26 
27 companion object {
28 @JvmStatic
29 @Parameterized.Parameters(name = "{0}")
30 fun themes() = TestTheme.values().toList()
31 }
32}

Beklenen Sonuçlar ve Mertebeler

Aşağıdaki değerler ölçülmüş tek bir projenin sonucu değil; CMP'yi iOS'ta production'a alan ekiplerin raporladığı tipik bantlar. Kendi baseline'ını ölçmeden karar verme:

Startup Time:

  • Android cold start: 650ms → 590ms bandı (tek codebase ile optimizasyon tek yerde yapılır)
  • iOS cold start: 780ms bandı (native SwiftUI uygulamayla kıyaslandığında ~%12 yavaş)

Frame Rate:

  • Android scroll: ortalama 59.8 fps
  • iOS scroll: ortalama 57.3 fps (60 fps hedefine yakın)
  • Complex animation ekranları: Android 59.2 fps, iOS 55.8 fps

Memory Usage:

  • Android: native Compose uygulamaya göre %8 fazla
  • iOS: native SwiftUI uygulamaya göre %22 fazla (Kotlin/Native runtime overhead)

Code Sharing (hedef dağılım):

  • Shared (commonMain): %75-80
  • Android-specific: %12-15
  • iOS-specific: %8-10

Development Velocity:

  • Tek feature iki platform için tek seferde geliştirilir
  • Ortalama feature development süresinde üçte bire yakın kazanç raporlanıyor
  • Bug fix'ler tek bir yerde yapılır

🏆 HERO WOW Compose Multiplatform İpucu

Bu mimaride en sık tekrarlanan tavsiye: iOS'ta Compose kullanırken CADisplayLink tabanlı animasyonlar yerine Compose'un kendi animation API'lerini tercih edin. animateAsState, updateTransition ve Animatable gibi Compose animasyon API'leri, iOS Metal renderer ile sorunsuz çalışıyor ve Kotlin/Native bridge overhead'ini minimize ediyor. Native iOS animation callback'lerine geçiş yapmak cazip görünse de, bu yaklaşım genellikle daha fazla performans sorunu ve maintenance yükü yaratıyor.


🥚 Easter Egg: Gizli Compose iOS Özelliği

iOS'ta Compose Multiplatform, UIKitView ile herhangi bir UIKit widget'ını Compose içine gömmenizi sağlıyor. Ancak az bilinen bir özellik: UIKitInteropProperties ile UIKit view'un Compose gesture sistemiyle nasıl etkileşeceğini fine-tune edebilirsiniz. isInteractive = false ayarıyla UIKit view'u sadece display amaçlı kullanabilir, tüm gesture'ları Compose'a bırakabilirsiniz. Bu özellik özellikle WebView gibi karmaşık UIKit component'larını Compose scroll container içinde kullanırken hayat kurtarıyor.


🎁 Bonus: Ücretsiz Araçlar ve Kaynaklar

  • KMP Wizard (kmp.jetbrains.com): Proje scaffold aracı, dependency setup otomatik yapıyor
  • Compose Multiplatform Playground: Tarayıcıda CMP deneyin, iOS/Android önizleme yan yana
  • KMP-NativeCoroutines: Swift-Kotlin coroutine bridge kütüphanesi, async/await desteği
  • Touchlab SKIE: Kotlin sealed class ve coroutine'leri Swift-native API'ye dönüştürüyor
  • Ktorfit: Retrofit-style HTTP client, KMP-native

Sonuç

Compose Multiplatform 1.6, iOS production deployment için artık ciddi bir alternatif. %75-80 bandında kod paylaşımı ve makul performance trade-off'larıyla, özellikle Android-first şirketler için iOS'a genişleme maliyetini belirgin biçimde düşürüyor.

Memory management, bridge overhead ve Cupertino UX uyumu gibi konularda dikkatli olmak gerekiyor. Ancak tooling ve ekosistem hızla olgunlaşıyor; 2026 sonuna kadar performans farkının daha da kapanması bekleniyor.

Eğer ekibiniz Kotlin/Compose bilen Android geliştiricilerden oluşuyorsa ve iOS'a genişleme planınız varsa, Compose Multiplatform bugün production'a hazır.

İlgili yazılar:

Dış kaynaklar:

Etiketler

#Compose Multiplatform#CMP#Kotlin#Android#iOS#Shared UI#2026
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