First Export
This guide walks through exporting a simple Swift class and calling it from Kotlin.
1. Annotate Swift code
Section titled “1. Annotate Swift code”Create a Swift file in your target and annotate the types you want to expose with @jvm:
import Swift4j
@jvmclass GreetingService { func greet(name: String, _ response: (Greeting) -> Void) { response(Greeting(name: name)) }}
@jvmclass Greeting { let name: String
init(name: String) { self.name = name }
func getMessage() -> String { "Swift says hello to \(name)" }}Both types appear in the Kotlin signature of greet, so both must be annotated with @jvm.
2. Generate Kotlin bridging classes
Section titled “2. Generate Kotlin bridging classes”Run the generate-java-bridging SPM plugin from your package directory:
swift package plugin generate-java-bridging --product MyLibraryThe generated files are written to:
.build/plugins/generate-java-bridging/outputs/MyLibrary/main/java/Copy or symlink this directory into your Android or Java project’s source tree.
3. Build the native library
Section titled “3. Build the native library”swift build -c releaseThis produces libMyLibrary.dylib (macOS) or libMyLibrary.so (Linux/Android). Copy this file to wherever your JVM project expects native libraries.
4. Call from Kotlin
Section titled “4. Call from Kotlin”import MyLibrary.GreetingService
fun main() { System.loadLibrary("MyLibrary")
val service = GreetingService() service.greet("Kotlin") { greeting -> println(greeting.getMessage()) }}System.loadLibrary("MyLibrary") must be called before any Swift type is used. On Android, call it in Application.onCreate() or Activity.onCreate().
Next steps
Section titled “Next steps”- Classes — properties, static methods, object lifecycle
- Structs — value types and
inoutparameters - Closures — callbacks and lambda passing
- Code Generation — SPM plugin options and output structure