Skip to content
Published on

Kotlin Swift export가 Alpha가 됐다 — Objective-C 다리를 걷어내는 중이지만, 아직 건너지는 마십시오

공유하기
Authors

들어가며 — KMP가 iOS에서 내는 세금

Kotlin Multiplatform의 세일즈 문구는 늘 깔끔했습니다. 비즈니스 로직을 한 번 쓰고 Android와 iOS가 같이 쓴다. Android 쪽은 실제로 그렇게 됩니다 — 같은 언어, 같은 툴체인이니까요.

문제는 늘 iOS 쪽 경계면이었습니다. Kotlin/Native가 만들어 내는 결과물이 Swift가 바로 읽는 무언가가 아니었기 때문입니다. Kotlin은 Objective-C 프레임워크를 뱉고, Swift는 그 Objective-C 헤더를 Swift에서 보이는 API로 다시 번역해서 씁니다. 즉 Kotlin과 Swift 사이에 아무도 원하지 않은 제3의 언어가 끼어 있습니다. 둘 다 널 안정성을 타입에 담는 현대 언어인데, 그 사이 통역이 1984년산 언어인 셈입니다.

이 통역 비용은 추상적인 게 아닙니다. 아래에서 보겠지만 타입이 뭉개지고, 이름이 망가지고, 코루틴이 콜백으로 되돌아갑니다. Swift export는 이 다리를 아예 걷어내려는 시도이고, Kotlin 2.4.0(2026년 6월 3일 릴리스)에서 Alpha가 됐습니다.

Alpha가 됐다는 건 좋은 소식입니다. 그런데 "Alpha"가 JetBrains 사전에서 정확히 무슨 뜻인지 확인하고 나면, 지금 당장 마이그레이션 티켓을 끊을 마음은 사라질 겁니다. 이 글은 그 양쪽을 다 정리합니다.

Objective-C 다리가 실제로 부수는 것들

먼저 왜 이 기능이 존재하는지부터 봐야 합니다. Kotlin의 Objective-C interop 문서가 스스로 인정하는 손실들입니다.

프리미티브 박싱. 문서 표현 그대로, kotlin.Int의 박스는 Swift에서 KotlinInt 클래스 인스턴스로 표현됩니다. 이 클래스들은 NSNumber에서 파생되죠. 그리고 역방향은 자동으로 안 됩니다 — 문서는 NSNumber가 Swift/Objective-C 파라미터나 반환 타입으로 쓰일 때 Kotlin 프리미티브로 자동 변환되지 않는다고 명시합니다. 이유는 NSNumber가 감싼 값이 Byte인지 Boolean인지 Double인지에 대한 정보를 정적으로 갖고 있지 않기 때문이고, 그래서 수동으로 캐스팅해야 합니다. 널 가능한 정수 하나 넘기려고 힙 할당된 래퍼가 생기고, Swift 쪽에서 수동 캐스팅 코드가 생깁니다.

제네릭 손실. Objective-C의 "lightweight generics"는 Kotlin의 제네릭을 담기에 좁습니다. 문서가 못 박는 제약은 두 가지입니다. 첫째, 제네릭은 클래스에만 정의할 수 있고 인터페이스(Objective-C·Swift의 프로토콜)나 함수에는 정의할 수 없습니다. 둘째, 널 가능성이 뭉개집니다. 문서의 예를 그대로 옮기면, 이런 Kotlin 코드가

class Sample<T>() {
    fun myVal(): T
}

Swift에서는 이렇게 보입니다.

class Sample<T>() {
    fun myVal(): T?
}

TT?로 바뀌었습니다. Objective-C 헤더가 myVal을 널 가능으로 선언할 수밖에 없기 때문입니다. 문서가 권하는 우회는 T : Any 상한을 직접 걸어서 헤더가 non-null로 마킹하게 만드는 것 — 즉 Kotlin 쪽 API 설계를 Objective-C 헤더 사정에 맞춰 비틀라는 이야기입니다.

코루틴이 콜백이 됨. Kotlin의 suspend 함수는 생성된 Objective-C 헤더에서 콜백을 받는 함수, Swift 용어로는 컴플리션 핸들러로 나타납니다. Swift 5.5부터 async 함수로 부를 수 있는 길이 열리긴 했는데, 문서는 이 기능이 "highly experimental"이며 특정 제약이 있다고 적고 자세한 건 KT-47610을 보라고 합니다. 이 글을 쓰는 2026년 7월 16일 기준으로 그 이슈는 여전히 Open 상태입니다. 서브시스템은 Language Design과 Native. ObjC Export로 잡혀 있습니다. 몇 년째 열려 있는 이 이슈가, Swift export라는 별도 경로가 필요했던 이유를 압축해서 보여 줍니다.

이름 뭉개짐. Swift export 문서가 스스로 밝히는 동기가 이것입니다 — Objective-C의 헷갈리는 언더스코어와 뭉개진 이름(mangled names)을 없애는 것. 최상위 함수들이 어딘가의 SharedKt 같은 클래스에 붙어 나타나는 걸 본 적이 있다면 무슨 얘긴지 아실 겁니다.

정리하면, Objective-C 다리는 Kotlin API를 그대로 옮기지 못하고 Objective-C가 표현할 수 있는 부분집합으로 투영합니다. 손실은 설계상 불가피한 것이었습니다.

Swift export가 하는 일

Swift export의 아이디어는 단순합니다. 중간 언어를 빼는 것.

공식 문서의 첫 문장이 정확합니다 — Swift export는 Kotlin 소스를 직접 내보내서 Swift에서 Kotlin 코드를 관용적으로 호출하게 하고, Objective-C 헤더를 없앤다. 컴파일러가 swiftmodule 파일, 정적 .a 라이브러리, 헤더 파일, modulemap 파일을 직접 만들어 앱 빌드 디렉터리로 복사합니다.

설정은 Gradle 쪽 블록 하나입니다.

// build.gradle.kts
kotlin {
    iosArm64()
    iosSimulatorArm64()

    swiftExport {
        // 루트 모듈 이름
        moduleName = "Shared"

        // 패키지 접두사를 생성된 Swift 코드에서 제거
        flattenPackage = "com.example.sandbox"

        // 외부 모듈 export 설정
        export(project(":subproject")) {
            moduleName = "Subproject"
            flattenPackage = "com.subproject.library"
        }
    }
}

그리고 Xcode의 Build Phases에서 Run Script를 embedAndSignAppleFrameworkForXcode 대신 embedSwiftExportForXcode 태스크로 바꿔 줍니다. 문서가 제시하는 스크립트는 ./gradlew :<모듈 이름>:embedSwiftExportForXcode 형태입니다.

앞 절에서 본 손실 중 몇 개는 실제로 사라집니다. 문서가 나열하는 것들입니다.

  • 프리미티브 널 가능성 개선. Int? 같은 타입을 KotlinInt 래퍼로 박싱해야 했던 Objective-C interop과 달리, Swift export는 널 가능성 정보를 직접 변환합니다.
  • 멀티모듈 지원. Kotlin 모듈 하나가 Swift 모듈 하나로 나갑니다.
  • 패키지 보존. Kotlin 패키지가 명시적으로 보존되어 이름 충돌을 피합니다(중첩 Swift enum으로 번역됩니다).
  • 오버로드. Kotlin의 오버로드된 함수를 Swift에서 모호함 없이 부를 수 있습니다.
  • 타입 별칭. typealias가 Swift에 그대로 남습니다.

그리고 Kotlin 2.3.0(2025년 12월 16일)에서 두 가지가 더 붙었습니다. Kotlin enum class가 예전처럼 평범한 Swift 클래스로 나가지 않고 진짜 네이티브 Swift enum으로 매핑되기 시작했고, vararg 함수가 Swift의 가변 파라미터로 직접 매핑됐습니다.

2.4.0이 바꾼 것 — 승격, 그리고 코루틴

Kotlin 2.4.0 릴리스 노트가 말하는 이번 변화의 핵심은 두 가지입니다.

첫째, 구조적 동시성. Kotlin의 suspend 함수와 suspend 함수 타입이 Swift의 관용적 async로 나갑니다. 컴플리션 핸들러가 아니라요.

// Kotlin
suspend fun hello(): String {
    delay(1000)
    return "Hello Swift! This is Kotlin."
}
// Swift
let msg = try await hello()

둘째, Flow export. 이게 실무적으로 더 큽니다. 문서가 정확히 짚듯이, 이전까지 kotlinx.coroutines.flowFlow 인터페이스를 Swift로 노출하는 유일한 방법은 서드파티 솔루션이었습니다. 이제 Flow가 Swift의 AsyncSequence로 기본 활성화된 채 나가고, 타입 정보도 보존됩니다.

// Kotlin
fun flowOfStrings(): Flow<String> = flowOf("hello", "any", "world")
// Swift
var actual: [String] = []

// String 타입이 Kotlin에서 올바르게 추론됨
for try await element in flowOfStrings().asAsyncSequence() {
    actual.append(element)
}

KMP를 실제로 굴려 본 사람이라면 이 한 줄의 무게를 압니다. "Kotlin 쪽 상태 스트림을 SwiftUI에 어떻게 꽂나"는 KMP 도입 팀이 반드시 마주치는 질문이었고, 지금까지의 답은 항상 서드파티 래퍼였습니다.

기본 활성화라는 점도 짚어 둘 만합니다. Swift export 자체는 opt-in이지만, 그 안에서 Flow export는 따로 켤 필요가 없습니다.

승격의 기준선이 무엇이었는지도 흥미롭습니다. Kotlin 로드맵에 "Swift Export: Alpha release"라는 라벨로 걸려 있던 항목은 KT-80305인데, 티켓의 실제 제목은 "Support coroutines in Swift Export"입니다. 2026년 3월 24일에 Fixed로 닫혔고 2.4.0-Beta2에 들어갔습니다. 즉 Alpha의 문턱은 사실상 "코루틴이 되느냐"였습니다. 반대로 말하면, 코루틴이 안 되는 동안에는 이 기능이 iOS 앱의 실제 API 표면을 감당할 수 없다고 JetBrains 스스로 판단하고 있었다는 뜻이기도 합니다.

"Alpha"가 JetBrains 사전에서 뜻하는 것

여기서 정직해질 부분입니다. 많은 프로젝트에서 Alpha는 "곧 됩니다" 정도의 마케팅 단어지만, Kotlin은 이 등급을 문서에 정의해 뒀습니다. components-stability 문서의 정의를 그대로 옮기면 이렇습니다.

Alpha는 "we are testing whether this should become production-ready" — 이걸 프로덕션 레디로 만들어야 하는지를 시험하는 중이라는 뜻입니다. 그리고 이어지는 설명이 핵심입니다. 제품으로 만들 의도가 있고 사용자 가치와 시장 적합성을 검증해 최종 형태를 잡는 중이며, 기능 집합은 아직 불완전하고 파괴적 변경이 예상되며, 가설이 성립하지 않으면 기능을 크게 바꾸거나 중단할 수 있다("we may significantly change or discontinue the feature").

바로 아래 등급인 Beta의 정의와 비교해 보면 격차가 선명합니다. Beta는 "you can use it, we'll do our best to minimize migration issues for you" — 써도 된다, 마이그레이션 이슈를 최소화하려 최선을 다하겠다는 약속이 들어 있습니다. Alpha에는 그 약속이 없습니다. Kotlin 문서는 Experimental·Alpha·Beta를 묶어 pre-stable이라 부릅니다.

그리고 문서가 덧붙이는 한 문장을 그대로 옮길 가치가 있습니다 — 안정성 등급은 그 컴포넌트가 얼마나 빨리 Stable로 릴리스될지에 대해 아무것도 말하지 않는다. 즉 Alpha가 됐다고 해서 Beta나 Stable이 가깝다는 뜻이 전혀 아닙니다.

Swift export 문서 본문도 같은 톤입니다. "currently in Alpha and still incomplete, so breaking changes are expected."

현재 공개된 Kotlin 로드맵은 마지막 수정이 2026년 2월, 다음 갱신 예정이 2026년 8월로 적혀 있습니다. 그 로드맵에 걸린 Swift export 항목은 Alpha 릴리스까지이고, Beta나 Stable을 겨냥한 항목은 올라와 있지 않습니다. 2.4.0 다음 EAP인 2.4.20-Beta1(2026년 6월 24일) 릴리스 노트에도 Swift export 관련 변경은 없습니다. 다음 로드맵 갱신 전까지, 공개된 자료만으로 Beta 시점을 추정할 근거는 없습니다. 없는 날짜를 지어내느니 없다고 말하는 편이 낫습니다.

한 가지 더 — JetBrains 자신도 이번 릴리스에서 Swift export를 크게 홍보하지 않았습니다. 2.4.0 릴리스 블로그의 Kotlin/Native 요약 줄은 "Support for Swift packages as dependencies, updates on Swift export, and the CMS GC enabled by default"가 전부입니다. "updates on Swift export" — Alpha 승격을 헤드라인으로 뽑지 않았다는 것 자체가 하나의 신호입니다.

아직 못 하는 것들

문서의 "Current limitations" 절과 본문 주석에 흩어진 제약을 모으면 이렇습니다. 각각이 실제 프로젝트에서 어떻게 아픈지를 붙여 봅니다.

direct integration 전용. 이게 가장 큰 벽입니다. Swift export는 iOS 프레임워크를 Xcode 프로젝트에 연결할 때 direct integration을 쓰는 프로젝트에서만 동작합니다. iOS 통합 방식 문서를 보면 통합 경로는 다섯 갈래입니다 — direct integration, 로컬 Swift 패키지, 로컬 podspec CocoaPods(여기까지 local), 그리고 SwiftPM + XCFramework, CocoaPods + XCFramework(remote). Swift export는 이 중 하나만 지원합니다. 게다가 direct integration 자체가 "KMP 프로젝트에 CocoaPods 의존성을 import하지 않는 경우"에 쓰는 방식입니다. 정리하면 이렇습니다.

  • 공유 모듈을 XCFramework로 말아 별도 iOS 저장소에 던지는 조직 — 해당 없음.
  • KMP 쪽에서 CocoaPods 의존성을 당겨 쓰는 프로젝트 — 해당 없음.
  • IntelliJ IDEA의 KMP 플러그인이나 웹 마법사로 만든 모노레포 — 해당 됨.

이 제약은 새것도 아닙니다. Swift export가 처음 기본 제공된 Kotlin 2.2.20 릴리스 노트에 이미 같은 문장이 적혀 있었고, Alpha가 된 2.4.0 시점의 문서에도 그대로 남아 있습니다. 세 릴리스를 건너오는 동안 이 벽은 움직이지 않았습니다.

제네릭. 문서의 주석이 짧고 단호합니다 — "Generic types are generally not supported." 그리고 Swift로 내보낼 때 Kotlin 제네릭 타입 파라미터는 상한(upper bound)으로 타입 소거됩니다. 여기서 아이러니가 하나 생깁니다. 제네릭에 관한 한 Swift export는 아직 Objective-C 다리보다 나은 게 아닙니다. Objective-C는 적어도 클래스 위에서는 lightweight generics를 실어 나르는데, Swift export는 상한으로 지워 버리니까요. 앞 절에서 본 Sample<T> 예제의 널 가능성 문제가 해결되는 대신 타입 파라미터 자체가 사라지는 셈입니다.

클래스 제약. Swift export는 Any를 직접 상속하는 final 클래스만 지원합니다. class Foo() 같은 것들이죠. 즉 상속 계층이 있는 도메인 모델이나 sealed 계층을 그대로 내보낼 수 없습니다. 내보내진 클래스는 Swift에서 KotlinRuntime.KotlinBase를 상속한 클래스가 됩니다.

크로스 언어 상속 불가. Swift 클래스가 Kotlin에서 내보낸 클래스나 인터페이스를 직접 서브클래싱할 수 없습니다. Kotlin 쪽에 인터페이스를 정의하고 Swift에서 구현해 넘기는 패턴을 쓰고 있었다면 그대로는 못 옮깁니다.

컬렉션 상속 타입. List, Set, Map을 상속하는 타입은 export 과정에서 무시되고(KT-80416), 그 상속 타입들은 Swift 쪽에서 인스턴스화할 수 없습니다(KT-80417). 두 이슈 모두 2026년 7월 16일 현재 미해결이고, 상태는 Backlog입니다. Backlog는 "다음 릴리스에 잡혀 있다"가 아니라 "잡혀 있지 않다"는 뜻입니다. 참고로 두 티켓의 실제 제목은 문서의 요약보다 구체적입니다 — 각각 "function with receiver of MutableList is not translated"와 "ByteArray is impossible to instantiate"입니다. 후자를 보면 ByteArray 같은 흔한 타입이 걸린다는 게 드러납니다.

IDE 지원 없음. 문서가 명시합니다 — "No IDE migration tips or automation are available." Objective-C 경로에서 옮겨 오는 걸 도와주는 도구가 없습니다. 손으로 합니다.

opt-in의 번거로움. opt-in이 필요한 선언(예: kotlinx.datetime)을 쓰면 모듈 레벨에 명시적 optIn 컴파일러 옵션을 별도 블록으로 추가해야 합니다.

operator 제한. operator 수식자가 붙은 함수 지원은 현재 제한적이라고 문서가 적어 뒀습니다.

Int가 Int32가 되는 문제

제약 목록에는 안 들어 있지만, 매핑 표를 실제로 읽어 보면 눈에 걸리는 게 있습니다.

KotlinSwift
IntInt32
LongInt64
CharUnicode.UTF16.CodeUnit
AnyKotlinBase 클래스
UnitVoid
NothingNever

Kotlin의 Int는 Swift의 Int가 아니라 Int32로 갑니다. 타입 관점에서는 정확합니다 — Kotlin Int는 32비트가 맞고, Swift의 Int는 64비트 플랫폼에서 64비트니까 이걸 Int로 매핑하면 거짓말이 됩니다. 문서 예제가 보여 주는 결과는 이렇습니다.

// Kotlin
class MyClass {
    val property: Int = 0
}
// Swift
public class MyClass : KotlinRuntime.KotlinBase {
    public var property: Swift.Int32 { get }
}

정확하지만, Swift 쪽 호출부 입장에서는 관용적이지 않습니다. Swift 코드에서 정수를 다루는 기본형은 Int이고, 배열 인덱스도 Int이고, SwiftUI API도 Int를 받습니다. Kotlin에서 넘어온 Int32를 쓰려면 경계마다 변환이 붙습니다. KotlinInt 박싱이 사라진 자리에 Int32 변환이 들어온 셈입니다 — 훨씬 싼 거래인 건 분명하지만, "Swift에서 관용적으로 호출한다"는 목표가 아직 완전히 달성되진 않았다는 표시이기도 합니다. CharUnicode.UTF16.CodeUnit이 되는 것도 같은 종류의 정직한 불편입니다.

2.4.0의 나머지 Kotlin/Native 변화

Swift export만 본 김에, 같은 릴리스에서 Kotlin/Native에 들어간 것들도 짧게 정리해 둡니다. 이쪽이 오히려 지금 당장 여러분 빌드에 영향을 줍니다.

CMS GC가 기본이 됨. Kotlin 2.0.20에서 실험적으로 들어왔던 동시 마크 앤 스위프(CMS) GC가 2.4.0부터 기본값이 됐습니다. 기존 기본값이던 PMCS(parallel mark concurrent sweep)는 힙의 객체를 마킹하는 동안 애플리케이션 스레드를 멈춰야 했지만, CMS는 마킹 단계를 애플리케이션 스레드와 동시에 돌립니다. 릴리스 노트는 이것이 GC 일시정지 시간과 앱 반응성을 크게 개선한다고 적고, 근거로 Compose Multiplatform UI 앱 벤치마크를 듭니다 — JetBrains 자체 측정이고, 릴리스 노트 본문에는 구체적 수치가 제시돼 있지 않습니다. 문제가 생기면 gradle.propertieskotlin.native.binary.gc=pmcs로 되돌릴 수 있습니다.

Apple 타깃 최소 버전 상향. 이건 조용한 파괴적 변경입니다. iOS와 tvOS가 14.0에서 15.0으로, macOS가 11.0에서 12.0으로, watchOS가 7.0에서 8.0으로 올랐습니다. 더 낮은 버전을 지원해야 한다면 freeCompilerArgs-Xoverride-konan-properties=minVersion.ios=14.0 같은 옵션을 걸어야 합니다.

LLVM 21. Kotlin/Native의 LLVM이 19에서 21로 올라갔습니다. 릴리스 노트는 코드에 영향을 주지 않아야 한다고 적고 있습니다.

devirtualization 메모리 감소. 링크 릴리스 태스크가 특히 큰 프로젝트에서 메모리를 너무 많이 먹던 문제에 개선이 들어갔습니다. 릴리스 노트의 표현은 조심스럽게 옮길 필요가 있습니다 — "EAP 사용자 중 한 명의 벤치마크에 따르면" 링크 릴리스 태스크의 메모리 소비가 절반으로 줄어 최소 13GB를 절약했다고 합니다. 즉 JetBrains가 전한 사용자 1인의 자체 측정치이고, 프로젝트 규모·환경 조건은 공개되지 않았습니다. 여러분 프로젝트에서 같은 폭이 나온다는 보장은 전혀 없습니다.

Swift 패키지 import(Experimental). Gradle 설정에서 Swift 패키지를 iOS 앱의 의존성으로 선언할 수 있게 됐습니다. swiftPMDependencies 블록에 swiftPackage(url = ..., version = ..., products = ...) 형태로 적습니다. 로드맵 항목(KT-53877)은 아직 Open이고, 이 기능의 등급은 Alpha가 아니라 Experimental입니다.

그래서, 지금 써야 하나

판단은 이렇게 갈립니다.

지금 켜 볼 만한 경우

  • 새로 시작하는 KMP 프로젝트이고, direct integration 모노레포 구성이고, CocoaPods 의존성이 없다.
  • 공유 모듈의 공개 API가 단순하다 — 최상위 함수, final 데이터 클래스, enum, suspend 함수, Flow. 제네릭 컨테이너나 상속 계층을 Swift로 내보내지 않는다.
  • Swift 경계면이 계속 바뀌어도 감당할 수 있다. 파괴적 변경은 예상되는 게 아니라 예고된 것입니다.
  • 피드백을 남길 의사가 있다. Alpha 단계에서 JetBrains가 검증하려는 "가설"에 표를 던지는 셈입니다.

켜면 안 되는 경우

  • 공유 모듈을 XCFramework로 배포하거나 CocoaPods를 쓴다 — 애초에 안 됩니다. 선택지가 아니라 사실입니다.
  • 공개 API에 제네릭이 있다. 상한으로 소거되고, 문서가 "일반적으로 지원되지 않는다"고 적어 둔 영역입니다.
  • Swift 쪽에서 Kotlin 인터페이스를 구현하는 패턴을 쓴다 — 크로스 언어 상속이 없습니다.
  • 이미 Objective-C 경로가 돌아가고 있고 제품 일정이 있다. 지금 옮겨서 얻는 건 문법 미학과 AsyncSequence이고, 잃는 건 안정성 보장과 IDE 지원입니다. Beta 약속조차 아직 없는 등급으로 프로덕션 경계면을 옮길 이유가 없습니다.

현실적인 자세는 이렇습니다. Swift export는 방향이 옳고, 2.4.0의 코루틴·Flow 지원으로 처음으로 "실제 API 표면을 감당할 수 있는" 모양이 됐습니다. 그러니 브랜치 하나 파서 켜 보고, 여러분의 공유 모듈 공개 API가 저 제약 목록에 몇 번 걸리는지 세어 보십시오. 그 숫자가 여러분 팀의 마이그레이션 준비도이자, 다음 릴리스 노트를 읽을 때 무엇을 찾아야 하는지 알려 주는 체크리스트입니다. 프로덕션 브랜치를 옮기는 건 그다음 이야기고, 최소한 Beta 이후의 이야기입니다.

마치며

Kotlin Multiplatform이 iOS에서 오래 안고 있던 문제는 언어가 둘이 아니라 셋이었다는 것입니다. Objective-C 다리는 Kotlin의 타입을 Objective-C가 표현 가능한 부분집합으로 투영했고, 그 손실이 KotlinInt 박싱, 제네릭 소거, 컴플리션 핸들러로 나타났습니다. Swift export는 그 다리를 걷어냅니다. 2.2.20에서 Experimental로 등장해, 2.3.0에서 enum과 vararg를 챙기고, 2.4.0에서 코루틴과 Flow를 얻으며 Alpha가 됐습니다.

동시에 정직하게 볼 것도 분명합니다. JetBrains 자신의 정의로 Alpha는 프로덕션 레디가 되어야 하는지를 아직 시험 중인 단계이고, 가설이 틀리면 중단될 수도 있는 단계입니다. direct integration 전용이라는 제약은 세 릴리스 동안 문장 하나 안 바뀐 채 남아 있고, 제네릭은 오히려 옛 다리보다 못하며, IDE 지원은 없습니다. 공개 로드맵에는 Beta 항목이 없습니다.

그래서 결론은 이렇게 정리됩니다. Swift export는 KMP의 iOS 이야기가 끝난다는 신호가 아니라, 제대로 시작됐다는 신호입니다. 지금 할 일은 마이그레이션이 아니라 측정입니다 — 여러분의 API가 저 벽에 몇 번 부딪히는지 세어 두고, 2026년 8월 로드맵 갱신을 기다리십시오.

참고 자료