Skip to content

Enums

swift4j exports Swift enums in two ways depending on whether the cases have associated values.

Enums with no associated values map to Java/Kotlin enums:

import Swift4j
@jvm
enum Priority {
case low
case medium
case high
}
val p: Priority = Priority.high
println(p) // high

Pass enum values to and from exported functions normally:

@jvm
class Task {
static func label(for priority: Priority) -> String {
switch priority {
case .low: return "Low"
case .medium: return "Medium"
case .high: return "High"
}
}
}
println(Task.label(for: Priority.medium)) // Medium

Enums with associated values map to Kotlin sealed classes. Each case becomes a subclass of the sealed class, with the associated values as properties:

@jvm
enum NetworkResult {
case success(String)
case error(code: Int, message: String)
case loading
}

The generated Kotlin looks like:

sealed class NetworkResult {
class success(val value0: String) : NetworkResult()
class error(val code: Int, val message: String) : NetworkResult()
object loading : NetworkResult()
}

Use Kotlin when to pattern-match:

val result = Network.requestError()
val msg = when (result) {
is NetworkResult.success -> "OK: ${(result as NetworkResult.success).value0}"
is NetworkResult.error -> "Error ${result.code}: ${result.message}"
NetworkResult.loading -> "Loading..."
}
println(msg)

Cases without associated values become object singletons. Cases with a single unnamed associated value use value0, value1, etc. Cases with named associated values use those names directly.

Enum values can be passed as parameters and return values just like any other exported type:

@jvm
struct Network {
static func forward(_ result: NetworkResult) -> NetworkResult {
switch result {
case .success(let s): return .success("Forwarded: \(s)")
case .error(let i, let s): return .error(code: -i, message: s)
case .loading: return .loading
}
}
}
val original = NetworkResult.success("data")
val forwarded = Network.forward(original)