
После работы над мультиплатформенной библиотекой, которая собирала .framework и .aar артефакты, я пришел к выводу, что есть большое количество полезных вещей, уже есть в Kotlin, но многие из нас никогда о них не знали.
Одна из вещей, о которой вы обязательно должны позаботиться при создании мультиплатформенного проекта — это библиотеки, которые вы используете при разработке. Лучше всего стоит придерживаться решений, предоставленных Kotlin «из коробки».
Так, когда я попал в ситуацию, когда появилась необходимость сериализовать JSON документ, который нужно было использовать на двух платформах(iOS и Android), появились проблемы в компиляции проекта под iOS. После небольших поисков, я нашёл Kotlinx Serializtion library.
Если быть откровенным, я никогда не знал об этой библиотеки, так что эта публикация в большей степени для людей, которые так же как и я не знали об этом инструменте.
Процесс настройки проекта для использования плагина достаточно хорошо описан в репозитории на Гитхабе. Но я буду настраивать проект как для Android, так и для мультиплатформенного использования.
Единственное, что надо сделать при мультиплатформенной компиляции, нужно добавить зависимости в конец зависитмостей в вашем нативном grandle файле.
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' }
Сериализация
Чтобы сериализировать класс, просто добавьте перед ним аннотацию
@Serializableimport 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
