
Generates `Parcelable` implementations for Apple targets, enabling serialization/deserialization similar to Android's `kotlin-parcelize`. Supports various data types and custom parcelers, facilitating cross-platform code sharing.
Experimental Kotlin/Native compiler plugin that generates Parcelable implementations for Darwin (Apple) targets. Allows writing Parcelable classes for all Darwin targets, similary to the Android's kotlin-parcelize plugin. Can be also used together with the kotlin-parcelize plugin to write Parcelable classes in the commonMain source set.
Supported targets: ios, watchos, tvos and macos
Supported types:
String typeEnum classesParcelable classesList, MutableList, Set, MutableSet, Map, MutableMap of all supported typesApply the plugin in your build.gradle file.
// Root build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("com.arkivanov.parcelize.darwin:gradle-plugin:<version>)
}
}
// Module's build.gradle
plugins {
id("com.arkivanov.parcelize.darwin")
}The plugin automatically adds the runtime dependency to all Darwin source sets. However, if you need to use Parcelable interface or @Parcelize annotation in a shared source set (e.g. iosMain), you will need to add the runtime dependency manually.
kotlin {
sourceSets {
iosMain {
dependencies {
implementation "com.arkivanov.parcelize.darwin:runtime:<version>"
}
}
}
}The runtime dependency often needs to be exported to the Apple framework. This allows encoding and decoding Parcelable classes in Swift.
The plugin works similary to the Android's kotlin-parcelize plugin.
The runtime module provides the following:
Parcelable implementations for the annotated classes.Parcelize serializers.Parceler should be used for the annotated type.Parceler should be used for a particular type.Here is an example of some Parcelable classes:
@Parcelize
data class User(
val name: String,
val age: Int
) : Parcelable
@Parcelize
data class UserGroup(
val users: List<User>
) : ParcelableA complete example can be found here - sample.
An example of the generated code can be found here - SomeParcelable.kt.
Suppose there is a type that we don't own and it has to be included in a Parcelable class.
class SomeTypeYouDontOwn(val someValue: Int)
@Parcelize
data class Foo(
val data: SomeTypeYouDontOwn,
) : ParcelableThe above snippet won't compile because the compiler plugin doesn't know how to serialize SomeTypeYouDontOwn. Usually just implementing Parcelable interface and adding @Parcelize annotation would work, but not in this case, because we don't own that type. A solution is to write a custom parceler.
Write a Parceler object for that class.
internal object SomeTypeYouDontOwnParceler : Parceler<SomeTypeYouDontOwn> {
override fun create(coder: NSCoder): SomeTypeYouDontOwn =
SomeTypeYouDontOwn(
someValue = coder.decodeInt32ForKey(key = "someValue"),
)
override fun SomeTypeYouDontOwn.write(coder: NSCoder) {
coder.encodeInt32(value = someValue, forKey = "someValue")
}
}Now there are two ways of serializing that class.
@Parcelize
data class Foo(
val data: @WriteWith<SomeTypeYouDontOwnParceler> SomeTypeYouDontOwn,
) : Parcelable@TypeParceler<SomeTypeYouDontOwn, SomeTypeYouDontOwnParceler>
@Parcelize
data class Foo(
val data: SomeTypeYouDontOwn,
) : ParcelableThe plugin can be used to write Parcelable classes in the commonMain source set. The recommended way is to use Essenty library, its parcelable module bridges both Android and Darwin implementations in commonMain. There are APIs for state preservation as well.
commonMain source set:expect interface Parcelable
@OptIn(ExperimentalMultiplatform::class)
@OptionalExpectation
@Target(AnnotationTarget.CLASS)
expect annotation class Parcelize()androidMain source set (only needed if kotlin-parcelize plugin is used):actual typealias Parcelable = android.os.Parcelable
actual typealias Parcelize = kotlinx.parcelize.ParcelizeiosMain source set:actual typealias Parcelable = com.arkivanov.parcelize.darwin.Parcelable
actual typealias Parcelize = com.arkivanov.parcelize.darwin.ParcelizeParcelize:actual interface Parcelable
// No need to define Parcelize, it is optionalNow you should be able to use Parcelize feature as usual in the commonMain source set.
The code will be automatically generated for Android and iOS, without affecting all other targets.
There is no proper IDE support at the moment. So Parcelable classes in the iosMain source set
are highlighted as incomplete, but the code still compiles just fine. There are no IDE errors in the commonMain source set.
Some tests can be found here.
Twitter: @arkann1985
Experimental Kotlin/Native compiler plugin that generates Parcelable implementations for Darwin (Apple) targets. Allows writing Parcelable classes for all Darwin targets, similary to the Android's kotlin-parcelize plugin. Can be also used together with the kotlin-parcelize plugin to write Parcelable classes in the commonMain source set.
Supported targets: ios, watchos, tvos and macos
Supported types:
String typeEnum classesParcelable classesList, MutableList, Set, MutableSet, Map, MutableMap of all supported typesApply the plugin in your build.gradle file.
// Root build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("com.arkivanov.parcelize.darwin:gradle-plugin:<version>)
}
}
// Module's build.gradle
plugins {
id("com.arkivanov.parcelize.darwin")
}The plugin automatically adds the runtime dependency to all Darwin source sets. However, if you need to use Parcelable interface or @Parcelize annotation in a shared source set (e.g. iosMain), you will need to add the runtime dependency manually.
kotlin {
sourceSets {
iosMain {
dependencies {
implementation "com.arkivanov.parcelize.darwin:runtime:<version>"
}
}
}
}The runtime dependency often needs to be exported to the Apple framework. This allows encoding and decoding Parcelable classes in Swift.
The plugin works similary to the Android's kotlin-parcelize plugin.
The runtime module provides the following:
Parcelable implementations for the annotated classes.Parcelize serializers.Parceler should be used for the annotated type.Parceler should be used for a particular type.Here is an example of some Parcelable classes:
@Parcelize
data class User(
val name: String,
val age: Int
) : Parcelable
@Parcelize
data class UserGroup(
val users: List<User>
) : ParcelableA complete example can be found here - sample.
An example of the generated code can be found here - SomeParcelable.kt.
Suppose there is a type that we don't own and it has to be included in a Parcelable class.
class SomeTypeYouDontOwn(val someValue: Int)
@Parcelize
data class Foo(
val data: SomeTypeYouDontOwn,
) : ParcelableThe above snippet won't compile because the compiler plugin doesn't know how to serialize SomeTypeYouDontOwn. Usually just implementing Parcelable interface and adding @Parcelize annotation would work, but not in this case, because we don't own that type. A solution is to write a custom parceler.
Write a Parceler object for that class.
internal object SomeTypeYouDontOwnParceler : Parceler<SomeTypeYouDontOwn> {
override fun create(coder: NSCoder): SomeTypeYouDontOwn =
SomeTypeYouDontOwn(
someValue = coder.decodeInt32ForKey(key = "someValue"),
)
override fun SomeTypeYouDontOwn.write(coder: NSCoder) {
coder.encodeInt32(value = someValue, forKey = "someValue")
}
}Now there are two ways of serializing that class.
@Parcelize
data class Foo(
val data: @WriteWith<SomeTypeYouDontOwnParceler> SomeTypeYouDontOwn,
) : Parcelable@TypeParceler<SomeTypeYouDontOwn, SomeTypeYouDontOwnParceler>
@Parcelize
data class Foo(
val data: SomeTypeYouDontOwn,
) : ParcelableThe plugin can be used to write Parcelable classes in the commonMain source set. The recommended way is to use Essenty library, its parcelable module bridges both Android and Darwin implementations in commonMain. There are APIs for state preservation as well.
commonMain source set:expect interface Parcelable
@OptIn(ExperimentalMultiplatform::class)
@OptionalExpectation
@Target(AnnotationTarget.CLASS)
expect annotation class Parcelize()androidMain source set (only needed if kotlin-parcelize plugin is used):actual typealias Parcelable = android.os.Parcelable
actual typealias Parcelize = kotlinx.parcelize.ParcelizeiosMain source set:actual typealias Parcelable = com.arkivanov.parcelize.darwin.Parcelable
actual typealias Parcelize = com.arkivanov.parcelize.darwin.ParcelizeParcelize:actual interface Parcelable
// No need to define Parcelize, it is optionalNow you should be able to use Parcelize feature as usual in the commonMain source set.
The code will be automatically generated for Android and iOS, without affecting all other targets.
There is no proper IDE support at the moment. So Parcelable classes in the iosMain source set
are highlighted as incomplete, but the code still compiles just fine. There are no IDE errors in the commonMain source set.
Some tests can be found here.
Twitter: @arkann1985