iOS 경험이 거의 없는 Android 개발자 팀이 Compose Multiplatform으로 2개월 만에 출결 app을 양 platform에 출시하고 8개월 운영하며 마주한 native interoperability 문제를 소개한다. 공유 UI로 초기 제품은 실제 동작했지만, KMP 미지원 native SDK를 잇는 과정에서 여러 함정을 밟은 여정을 담는다.
핵심 포인트- KMP가 공유하던 domain·network logic을 Compose Multiplatform이 declarative UI까지 넓혀 Swift 문법 없이 iOS 화면을 작성, 150명에게 MVP 배포
- push event·store version check·Firebase처럼 native가 흐름을 주도하는 SDK는 expect/actual만으로 안정적 data flow를 만들기 어려워, iOS source set에 public bridge와 MutableStateFlow를 두고 Swift callback이 flow를 갱신하면 ComposeUIViewController가 lifecycle-aware하게 수집해 recomposition
- Crashlytics는 Kotlin에 delegate interface를 두고 Swift 구현체를 주입하는 IoC로 연결했으나, shared와 composeApp을 별도 XCFramework로 compile하자 singleton이 서로 다른 memory instance가 되어 injection이 사라져 결국 shared를 합치며 module isolation을 포기
- Kotlin Native CocoaPods Gradle plugin으로 pod을 iOS source set에 직접 설치하면 Swift delegate 없이 actual 구현에서 Firebase를 부를 수 있다는 더 단순한 대안을 뒤늦게 확인, 8개월 운영 결과 UI 100%·전체 code 약 97%를 Kotlin으로 유지
왜 읽나Compose Multiplatform으로 iOS까지 대응하려는 Android 팀에게, native SDK 경계에서 StateFlow bridge·delegate injection·CocoaPods 대안이 각각 언제 맞는지 실전 시행착오로 알려준다.