📜 ⬆️ ⬇️

Serialization of Kotlin using Kotlinx.Serialization



After working on a multiplatform library that collected .framework and .aar artifacts, I came to the conclusion that there are a lot of useful things already in Kotlin, but many of us never knew about them.

One of the things that you must take care when creating a multiplatform project is the libraries that you use when developing. Best adhere to the solutions provided by Kotlin out of the box.
So, when I got into a situation when it became necessary to serialize a JSON document that needed to be used on two platforms (iOS and Android), there were problems in compiling an iOS project. After a bit of searching, I found the Kotlinx Serializtion library .
To be frank, I never knew about this library, so this publication is more for people who, like me, did not know about this tool.

The process of setting up a project for using the plugin is well described in the repository on GitHub But I will customize the project both for Android and for multi-platform use.

The only thing that needs to be done in multiplatform compilation is to add dependencies to the end of the dependencies in your native Grundle file.

implementation org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:0.9.1 

Grundle example for multiplatform use


 plugins { id 'kotlin-multiplatform' version '1.3.11' id 'kotlinx-serialization' version '1.3.10' } repositories { google() jcenter() mavenCentral() maven { url "https://kotlin.bintray.com/kotlinx" } } apply plugin: 'com.android.library' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 28 defaultConfig { minSdkVersion 15 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' androidTestImplementation 'com.android.support.test:runner:1.0.2' } kotlin { targets { fromPreset(presets.android, 'android') // Пресет для эмулятора iPhone // Поменяйте гп presets.iosArm64 (или iosArm32) чтобы собрать библиотеку для iPhone fromPreset(presets.iosX64, 'ios') { compilations.main.outputKinds('FRAMEWORK') } } sourceSets { commonMain { dependencies { implementation 'org.jetbrains.kotlin:kotlin-stdlib-common' implementation 'org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.9.1' } } commonTest { dependencies { implementation 'org.jetbrains.kotlin:kotlin-test-common' implementation 'org.jetbrains.kotlin:kotlin-test-annotations-common' } } androidMain { dependencies { implementation 'org.jetbrains.kotlin:kotlin-stdlib' } } androidTest { dependencies { } } iosMain { dependencies{ implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:0.9.1" } } iosTest { } } } 

For Android


 apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlinx-serialization' android { compileSdkVersion 28 defaultConfig { applicationId "com.example.smile.kotlinxretrosample" minSdkVersion 16 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.9.1" implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support:design:28.0.0' implementation 'com.squareup.retrofit2:retrofit:2.5.0' implementation 'com.squareup.okhttp3:okhttp:3.12.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' } 

Serialization


To serialize a class, simply add the @Serializable annotation in front of it @Serializable

 import kotlinx.serialization.Serializable @Serializable class Field { var length: Int = 0 var hint: String = "" var required: Boolean = false } 

Serialization works with data classes

Now, let's try to write a small example for converting JSON into an object and back.

 /* * { length = 20 hint = "example" required= false } */ fun toObject(stringValue: String): Field { return JSON.parse(Field.serializer(), stringValue) } fun toJson(field: Field): String { // Обратите внимание, что мы вызываем Serializer, который автоматически сгенерирован из нашего класса // Сразу после того, как мы добавили аннотацию @Serializer return JSON.stringify(Field.serializer(), field) } 

@Transient and @Optional


Two more annotations about which are worth telling this:


 @Optional var isOptional: Boolean = false @Transient var isTransient: Boolean = false 

An example for Android using Retrofit


For those who want to use this plugin in the development for Android, Retrofit 2 has an adapter. Link to the adapter .

A bit of code:

 un createRetrofit(): Retrofit { val contentType = MediaType.get("application/json") return Retrofit.Builder() .addConverterFactory(serializationConverterFactory(contentType, JSON)) .baseUrl(BASE_URL) .client(provideOkhttpClient()) .build() } 

If your class already has annotations, then after sending the request, your class should turn into a JSON object.

In general, serialization in Kotlin is an excellent addition to any project and makes the process of storing data in a string or a JSON object much simpler and less laborious.

List of repositories


  1. KotlinxRetrofit - a small working example of using serialization on Android
  2. kotlinx.serialization - The main library repository

JakeWharton / retrofit2-kotlinx serialization-converter - adapter for Retrofit

Source: https://habr.com/ru/post/437726/