Skip to content

First Export

This guide walks through exporting a simple Swift class and calling it from Kotlin.

Create a Swift file in your target and annotate the types you want to expose with @jvm:

import Swift4j
@jvm
class GreetingService {
func greet(name: String, _ response: (Greeting) -> Void) {
response(Greeting(name: name))
}
}
@jvm
class 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.

Run the generate-java-bridging SPM plugin from your package directory:

Terminal window
swift package plugin generate-java-bridging --product MyLibrary

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

Terminal window
swift build -c release

This produces libMyLibrary.dylib (macOS) or libMyLibrary.so (Linux/Android). Copy this file to wherever your JVM project expects native libraries.

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().

  • Classes — properties, static methods, object lifecycle
  • Structs — value types and inout parameters
  • Closures — callbacks and lambda passing
  • Code Generation — SPM plugin options and output structure