Kotlin Multiplatform despite all of its benefits sometimes has its own challenges. One of these challenges we recently faced was creating Parcelable objects in the shared module for the Android platform. After a little searching, I found this suggestion from
here. And in this tutorial, I want to show you how to address this challenge, in the way he’s said.
This tutorial consists of two parts:
- Getting familiar with type alias and their usage in Kotlin multiplatform projects.
- Learning how to create Parcelable classes in Kotlin multiplatform using type alias.
1. Typealias
As the Kotlin documentation says:
Type aliases provide alternative names for existing types. If the type name is too long you can introduce a different shorter name and use the new one instead.
The concept is very simple and just for clarity, I show you an example.
Assume that you are using a prebuilt class that has a long and inappropriate name, like this:
class TooLongAndUglyNameClass |
By using type alias you can change the name of the class in your project and use it in your code. It means by using your preferred class name you can build a new instance of the class.
typealias MyClass = TooLongAndUglyNameClass | |
fun foo(p: MyClass) { | |
// Some logics | |
} |
Typealias in Kotlin multiplatform
In Kotlin multiplatform projects, by declaring a class with except keyword in the commonMain directory, if, in one of the platforms, already there is a class that has all the methods with the exact signature of the expected class, by using type alias in that platform we can map the name of the class to the expected name.
Assume we have an expected interface in the commonMain directory like this:
// commonMain/Platform.kt | |
expect interface CommonParcelable |
Then on the Android platform, we want to map the Android Parcelable interface to it.
So we achieve this by using type alias for actual interface in the androidMain, like this:
// androidMain/Platform.kt | |
actual typealias CommonParcelable = Parcelable |
In this way, by implementing the CommonParcelable interface, on the Android platform, the Android Parcelable will be used.
2. Creating Parcelable classes in kotlin multiplatform
The first step is adding the kotlin-parcelize
plugin to the shared module build.gralde file, till being able to use Parcelize
annotation:
// shared module | |
plugins { | |
... | |
id("kotlin-parcelize") | |
} |
As you know in regular Android projects if we want to make a class Parcelable, we should add the Parcelize annotation to it and implement the Parcelable interface. So in the commonMain directory, we must create an annotation for the Parcelize and an interface for the Parcelabe.
In the commonMain directory create an annotation and name it CommonParceLize:
// commonMain/Platform.kt | |
@OptIn(ExperimentalMultiplatform::class) | |
@OptionalExpectation | |
@Target(AnnotationTarget.CLASS) | |
@Retention(AnnotationRetention.BINARY) | |
expect annotation class CommonParcelize() |
Job Offers
This annotation is like the Parcelize annotation, having all its annotations with two more annotations which are:
- @OptIn(ExperimentalMultiplatform::class): because we are using OptionalExpecation which is currently experimental.
- OptionalExpecation: marks an expected annotation class that it isn’t required to have actual counterparts in all platforms, it means our CommonParcelize annotation is allowed to have no corresponding actual class in ios or other platforms.
Then in the commonAndroid directory, we create the actual CommonParcelize and map the Parcelize annotation to it using type alias:
// androidMain/Platform.kt | |
actual typealias CommonParcelize = Parcelize |
Note: Because we’ve added OptionalExpectation annotation, there is no need to create corresponding actual classes in other platforms.
For the Parcelable we act like the Parcelize, so first in the commonMain, we create an expected interface and name it CommonParcelable:
// commonMain/Platform.kt | |
expect interface CommonParcelable |
And in the androidMain:
// androidMain/Pltafrom.kt | |
actual typealias CommonParcelable = Parcelable |
Also for other platforms
// ios/js/...Main | |
actual interface CommonParcelable |
Everything is done and now all we need is to use our annotation and interface
// CommonMain | |
@CommonParcelize | |
data class User( | |
val id: Int, | |
val firstname: String | |
): CommonParcelable |
In this way, on the Android platform, Parcelize instead of CommonParcelize and Parcelable instead of CommonParcelable will be used. And in other platforms, the CommonParcelize will be ignored because we’ve not declared the actual corresponding classes for them, and the CommonParcelable itself will be used which is an interface with no methods.
You can find the source code here:
I hope you found this tutorial helpful and enjoyed it, thanks for the devoted time.