После работы над мультиплатформенной библиотекой, которая собирала .framework и .aar артефакты, я пришел к выводу, что есть большое количество полезных вещей, уже есть в Kotlin, но многие из нас никогда о них не знали.
Одна из вещей, о которой вы обязательно должны позаботиться при создании мультиплатформенного проекта — это библиотеки, которые вы используете при разработке. Лучше всего стоит придерживаться решений, предоставленных Kotlin «из коробки».
Так, когда я попал в ситуацию, когда появилась необходимость сериализовать JSON документ, который нужно было использовать на двух платформах(iOS и Android), появились проблемы в компиляции проекта под iOS. После небольших поисков, я нашёл Kotlinx Serializtion library.
Если быть откровенным, я никогда не знал об этой библиотеки, так что эта публикация в большей степени для людей, которые так же как и я не знали об этом инструменте.
Процесс настройки проекта для использования плагина достаточно хорошо описан в репозитории на Гитхабе. Но я буду настраивать проект как для Android, так и для мультиплатформенного использования.
Единственное, что надо сделать при мультиплатформенной компиляции, нужно добавить зависимости в конец зависитмостей в вашем нативном Grundle файле.
implementation org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:0.9.1
Пример Grundle для мультиплатформенного использования
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 {
}
}
}
Для 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'
}
Сериализация
Чтобы сериализировать класс, просто добавьте перед ним аннотацию
@Serializable
import kotlinx.serialization.Serializable
@Serializable
class Field {
var length: Int = 0
var hint: String = ""
var required: Boolean = false
}
Серилиазация работает и с классами данных
Теперь, попробуем написать небольшой пример для преобразования JSON в объект и обратно.
/*
* {
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
и @Optional
Еще две аннотации о который стоит рассказать это:
@Transient
— Покажет Serializer'y что поле нужно проигнорировать.@Optional
— Serializer не остановиться и не выкинет ошибку, если поле отсутствует, но в тоже самое время значение по-умолчанию все равно должно быть установлено.
@Optional
var isOptional: Boolean = false
@Transient
var isTransient: Boolean = false
Пример для Android с использованием Retrofit
Для тех, кто хочет использовать этот плагин в разработке для Андроида, Retrofit 2 имеет адаптер. Ссылка на адаптер.
Чуть-чуть кода:
un createRetrofit(): Retrofit {
val contentType = MediaType.get("application/json")
return Retrofit.Builder()
.addConverterFactory(serializationConverterFactory(contentType, JSON))
.baseUrl(BASE_URL)
.client(provideOkhttpClient())
.build()
}
Если ваш класс уже имеет аннотации, то после отправки запроса ваш класс должен превратиться в JSON объект.
В общем, сериализация в Kotlin'e является отличным дополнением для любого проекта и делает сам процесс сохранения данных в строчке или JSON объекте гораздо более простым менее трудозатратным.
Список репозиториев
- KotlinxRetrofit — небольшой работащий пример использования сериализации на Android
- kotlinx.serialization — Основной репозиторий библиотеки
JakeWharton/retrofit2-kotlinx-serialization-converter — адаптер для Retrofit
yoshka
Кажется, ссылка на оригинал потерялась.