How to use Kotlin multiplatform sealed class in Swift

How to use Kotlin multiplatform sealed class in Swift

How to use Kotlin multiplatform sealed class in Swift

Learn how to transform your sealed class into Swift enums

How to use Kotlin multiplatform sealed class in Swift
How to use Kotlin multiplatform sealed class in Swift

Learn how to transform your sealed class into Swift enums

Learn how to transform your sealed class into Swift enums

Learn how to transform your sealed class into Swift enums

The problem

If you intend to use a sealed class from a Kotlin multiplatform module in a Swift client, you can access the information, but you won’t be able to use it as an enum in Swift. This is because the generated Swift code for a sealed class does not translate to an enum in Swift.

Indeed if you define a sealed class, such as the one shown below:

sealed class Destination(val path: String, val icon: ImageVector) { object Home : Destination("home", Icons.Rounded.Home) object Storybook : Destination("storybook", Icons.Rounded.Refresh) object Settings : Destination("settings", Icons.Rounded.Settings) }

The only possible way to instantiate a Destination in Swift is as follows:

let destination: Destination = Destination.Home()

when we want to do this :

let destination: Destination = .home

So, how to make these sealed classes more Swift-friendly?

Solution

We are going to use KSwift library, a Swift-friendly api generator for Kotlin/Native frameworks.

Add in root build.gradle

buildscript { repositories { mavenCentral() google() gradlePluginPortal() } dependencies { classpath("dev.icerock.moko:kswift-gradle-plugin:<latest>") } }

Add in project build.gradle

plugins { id("dev.icerock.moko.kswift") } kswift { install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature) }

Rebuild the project and the kswift library generated for us the Swift api and now we can access to the sealed class in a more Swift way :

let destination: Destination = .home

The problem

If you intend to use a sealed class from a Kotlin multiplatform module in a Swift client, you can access the information, but you won’t be able to use it as an enum in Swift. This is because the generated Swift code for a sealed class does not translate to an enum in Swift.

Indeed if you define a sealed class, such as the one shown below:

sealed class Destination(val path: String, val icon: ImageVector) { object Home : Destination("home", Icons.Rounded.Home) object Storybook : Destination("storybook", Icons.Rounded.Refresh) object Settings : Destination("settings", Icons.Rounded.Settings) }

The only possible way to instantiate a Destination in Swift is as follows:

let destination: Destination = Destination.Home()

when we want to do this :

let destination: Destination = .home

So, how to make these sealed classes more Swift-friendly?

Solution

We are going to use KSwift library, a Swift-friendly api generator for Kotlin/Native frameworks.

Add in root build.gradle

buildscript { repositories { mavenCentral() google() gradlePluginPortal() } dependencies { classpath("dev.icerock.moko:kswift-gradle-plugin:<latest>") } }

Add in project build.gradle

plugins { id("dev.icerock.moko.kswift") } kswift { install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature) }

Rebuild the project and the kswift library generated for us the Swift api and now we can access to the sealed class in a more Swift way :

let destination: Destination = .home

The problem

If you intend to use a sealed class from a Kotlin multiplatform module in a Swift client, you can access the information, but you won’t be able to use it as an enum in Swift. This is because the generated Swift code for a sealed class does not translate to an enum in Swift.

Indeed if you define a sealed class, such as the one shown below:

sealed class Destination(val path: String, val icon: ImageVector) { object Home : Destination("home", Icons.Rounded.Home) object Storybook : Destination("storybook", Icons.Rounded.Refresh) object Settings : Destination("settings", Icons.Rounded.Settings) }

The only possible way to instantiate a Destination in Swift is as follows:

let destination: Destination = Destination.Home()

when we want to do this :

let destination: Destination = .home

So, how to make these sealed classes more Swift-friendly?

Solution

We are going to use KSwift library, a Swift-friendly api generator for Kotlin/Native frameworks.

Add in root build.gradle

buildscript { repositories { mavenCentral() google() gradlePluginPortal() } dependencies { classpath("dev.icerock.moko:kswift-gradle-plugin:<latest>") } }

Add in project build.gradle

plugins { id("dev.icerock.moko.kswift") } kswift { install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature) }

Rebuild the project and the kswift library generated for us the Swift api and now we can access to the sealed class in a more Swift way :

let destination: Destination = .home

Share on X
Share on LinkedIn
Share on Facebook

Free AppKickstarter version (save 1 day)

I'm passionate about making Kotlin and Compose Multiplatform resources widely accessible. That's why I've created a free template just for you. Claim yours now!

Get Free Template