How to read file with okio inside commanMain module in a Kotlin Multiplatform Project? - kotlin

I am trying to read/write files in the commonMain module.
I created a new Kotlin Multiplatform App for Android and iOS using the Android Studio Wizard. (New -> New Project ... -> Koltin Multiplatform App)
Then I added okio as dependency to common in the shared/build.gradle.kts file.
sourceSets {
val okio = "3.3.0"
val commonMain by getting {
dependencies {
implementation("com.squareup.okio:okio:$okio")
}
}
...
In the module commonMain I cannot access FileSystem.SYSTEM (Unresolved Reference: SYSTEM) and therefore not read or write any files.
In the module iOSMain and androidMain I can access FileSystem.SYSTEM. Is this expected behaviour? This would require me to write an expected/actual mapping for all okio apis. Or is there an other way?
Or do I need to configure my project differently to be able to access FileSystem.SYSTEM inside the commonMain-Module?
shared/build.gradle
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
id("com.android.library")
}
kotlin {
android()
iosX64()
iosArm64()
iosSimulatorArm64()
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
version = "1.0"
ios.deploymentTarget = "14.1"
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "shared"
}
}
sourceSets {
val okio = "3.3.0"
val commonMain by getting {
dependencies {
implementation("com.squareup.okio:okio:$okio")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val androidMain by getting
val androidTest by getting
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
val iosX64Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val iosTest by creating {
dependsOn(commonTest)
iosX64Test.dependsOn(this)
iosArm64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
}
}
}
android {
namespace = "de.pixel.kmmpodstryout"
compileSdk = 32
defaultConfig {
minSdk = 21
targetSdk = 32
}
}
Greetings.kt in commonMain from the sample app generated by the wizard:
package de.pixel.kmmpodstryout
import okio.FileSystem
import okio.Path.Companion.toPath
class Greeting {
private val platform: Platform = getPlatform()
fun greet(): String {
val path = "helloworld.txt".toPath()
FileSystem.SYSTEM <--- "Unresolved Reference SYSTEM"
return "Hello, ${platform.name} ${readFile()}!"
}
}

Related

KMM & KMP share business logic with react app

We are trying to build single business logic with kmm to share it with ios and android and react project
IOS Project contains
swiftUI
cocoapods
react
typescript and react framework
package.json
the ios and react project doesn't include any kotlin code the business logic is compiled to .framework library and configured by default how do the same? build business logic as js library?
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
kotlin("plugin.serialization") version "1.7.21"
id("com.android.library")
}
kotlin {
android()
iosX64()
iosArm64()
iosSimulatorArm64()
js {
browser {
webpackTask {
output.libraryTarget = "commonjs2"
}
}
binaries.executable()
}
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
version = "1.0"
ios.deploymentTarget = "14.1"
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "shared"
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation(Coroutines.coroutinesCore)
implementation(Ktor.ktorCore)
implementation(Ktor.ktorContentNegotiation)
implementation(Ktor.ktorLogging)
implementation(Ktor.ktorSerializationJson)
implementation(SLF4j.slf4j)
implementation(Koin.koinCore)
implementation(MultiplatformSettings.settings)
implementation(Json.gson)
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val androidMain by getting {
dependencies {
implementation(Ktor.ktorAndroid)
}
}
val androidTest by getting
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
dependencies {
implementation(Ktor.ktorIos)
}
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
val iosX64Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val iosTest by creating {
dependsOn(commonTest)
iosX64Test.dependsOn(this)
iosArm64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
}
val jsMain by getting {
dependsOn(commonMain)
dependencies {
implementation(Ktor.ktorJs)
}
}
}
}
android {
namespace = "com.sample.kmm"
compileSdk = 33
defaultConfig {
minSdk = 21
targetSdk = 33
}
}
Kotlin Multiplatform share business logic with react project like ios

Unresolved reference: OkHttp in ktor

I am adding OkHttp in HttpClient. But I am getting error. Unresolved reference: OkHttp. I tried to add library in commonMain of build.gradle.kts, but I think I am missing some steps or doing something wrong. I want to use ktor Http but getting weird issue on my side. Can someone guide me, what am I am missing in my code?
import io.ktor.client.*
import io.ktor.client.engine.*
import io.ktor.client.engine.okhttp.*
fun createHttpClient() {
val client = HttpClient(OkHttp)
}
build.gradle.kts
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
id("com.android.library")
}
version = "1.0"
kotlin {
android()
iosX64()
iosArm64()
iosSimulatorArm64()
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
ios.deploymentTarget = "14.1"
framework {
baseName = "kotlinmultiplatformsharedmodule"
}
}
sourceSets {
val commonMain by getting{
dependencies {
implementation("io.ktor:ktor-client-okhttp:2.0.0")
implementation("io.ktor:ktor-client-core:2.0.0")
implementation("io.insert-koin:koin-core:3.2.0-beta-1")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val androidMain by getting
val androidTest by getting
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
val iosX64Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val iosTest by creating {
dependsOn(commonTest)
iosX64Test.dependsOn(this)
iosArm64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
}
}
}
android {
compileSdk = 32
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdk = 21
targetSdk = 32
}
}
Since OkHttp is designed to work on JVM and Android, you can't use it in the common code. You can create a different engine for each platform and inject it into the common code.
Or you can use expect-actual, see: https://ktor.io/docs/http-client-engines.html#mpp-config. You create an expect fun createHttpClient(): HttpClient in the common code, and actual fun createHttpClient(): HttpClient with the implementation for corresponding platform in each of the platform modules.

Project 'kotlinmultiplatformsharedmodule' not found in root project 'Kotlin Multiplatform'

Hey I am learning to KMM with swift package manager. I am trying to build swiftpackage, but when I tried it giving me error on build. I am learning this form here. I am getting error when I run this command. I am adding my video. This is my project link. Can someone guide me what I am doing wrong here?
./gradlew kotlinmultiplatformsharedmodule:createSwiftPackage
build.gradle.kts
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework
plugins {
kotlin("multiplatform")
id("com.android.library")
id("com.chromaticnoise.multiplatform-swiftpackage") version "2.0.3"
}
kotlin {
multiplatformSwiftPackage {
packageName("kotlinmultiplatformsharedmodule")
swiftToolsVersion("5.3")
targetPlatforms {
iOS { v("13") }
}
outputDirectory(File("../app/"))
}
android()
val xcf = XCFramework()
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = "kotlinmultiplatformsharedmodule"
xcf.add(this)
}
}
sourceSets {
val commonMain by getting
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val androidMain by getting
val androidTest by getting
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
val iosX64Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val iosTest by creating {
dependsOn(commonTest)
iosX64Test.dependsOn(this)
iosArm64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
}
}
}
android {
compileSdk = 32
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdk = 21
targetSdk = 32
}
}

Plugin [id: 'org.jetbrains.kotlin.multiplatform'] was not found in any of the following sources:

I am trying to set up Kotlin Multiplatform Library in my android existing application, but getting the following error:
Build file '/Users/tomtharakan/Documents/Projects/android/MyApplication/kmmsharedmodule/build.gradle.kts' line: 1
Plugin [id: 'org.jetbrains.kotlin.multiplatform'] was not found in any of the following sources:
Gragle Config:
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
id("com.android.library")
}
version = "1.0"
kotlin {
android()
iosX64()
iosArm64()
//iosSimulatorArm64() sure all ios dependencies support this target
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
ios.deploymentTarget = "14.1"
framework {
baseName = "kmmsharedmodule"
}
}
sourceSets {
val commonMain by getting
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:4.13.2")
}
}
val iosX64Main by getting
val iosArm64Main by getting
//val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
//iosSimulatorArm64Main.dependsOn(this)
}
val iosX64Test by getting
val iosArm64Test by getting
//val iosSimulatorArm64Test by getting
val iosTest by creating {
dependsOn(commonTest)
iosX64Test.dependsOn(this)
iosArm64Test.dependsOn(this)
//iosSimulatorArm64Test.dependsOn(this)
}
}
}
android {
compileSdk = 30
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdk = 21
targetSdk = 30
}
}

Getting kotlinx serialization working in multiplatform project

I'm taking Kotlin seriazliation for a test drive in a multiplatform project in Kotlin 1.4-M2, following the tutorial on github, but i'm not getting the serialization bit to compile.
This is my build.gradle.kts
plugins {
val kotlinVersion = "1.4-M2"
kotlin("multiplatform") version kotlinVersion
kotlin("plugin.serialization") version kotlinVersion
}
repositories {
mavenCentral()
maven {
url = uri("https://dl.bintray.com/kotlin/kotlin-eap")
}
maven {
url = uri("https://kotlin.bintray.com/kotlinx")
}
jcenter()
gradlePluginPortal()
}
kotlin {
jvm {
compilations.all {
kotlinOptions.jvmTarget = "11"
}
}
js(IR) {
moduleName = "hotel"
browser {
dceTask {
keep(
...
)
}
binaries.executable()
}
}
sourceSets {
// val serializationVersion = "0.20.0-1.4-M2"
val serializationVersion = "0.20.0"
val commonMain by getting {
dependencies {
implementation(kotlin("stdlib-common"))
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val jvmMain by getting {
dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation(kotlin("reflect"))
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion")
}
}
val jvmTest by getting {
dependencies {
implementation(kotlin("test-junit"))
}
}
val jsMain by getting {
dependencies {
implementation(kotlin("stdlib-js"))
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion")
}
}
val jsTest by getting {
dependencies {
implementation(kotlin("test-js"))
}
}
all {
languageSettings.enableLanguageFeature("InlineClasses")
}
}
}
I've tried it on a simple data class
#Serializable
data class Test(
val blah: Int = 0
)
import kotlinx.serialization.json.Json <<<--- Unresolved reference: kotlinx
import kotlinx.serialization.json.JsonConfiguration <<<--- Unresolved reference: kotlinx
import kotlin.js.ExperimentalJsExport
import kotlin.js.JsExport
...
fun main() {
val json = Json(JsonConfiguration.Default)
val jstring = json.toJson(Test.serializer(), Test(blah = 3))
println(jstring.toString())
}
It's complaining about Unresolved reference: kotlinx
Is there something specific one needs to do to make kotlinx imports work or should i be using different versions of the serializer libraries?
I got some help on Slack, thanks Sergey!
https://kotlinlang.org/eap/ shows the versions compatible with the EAP
or Milestone releases. You should use the serialization runtime
version 0.20.0-1.4-M2. Note that with this version, you need to add a
single dependency on kotlinx-serialization-runtime in the commonMain
source set, not separate dependencies on
kotlinx-serialization-runtime-common and the platform parts. See the
Specifying dependencies only once section here:
https://blog.jetbrains.com/kotlin/2020/06/kotlin-1-4-m2-released
So in short, my plugin should be matching my Kotlin version
plugins {
val kotlinVersion = "1.4-M2"
kotlin("multiplatform") version kotlinVersion
kotlin("plugin.serialization") version kotlinVersion
}
then under sourceSets, i should be using a single dependency instead of one per platform
sourceSets {
val serializationVersion = "0.20.0-1.4-M2"
val commonMain by getting {
dependencies {
implementation(kotlin("stdlib-common"))
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion")
}
}
JVM and JS Main should not have any serialization plugin, so those lines should be removed
val jvmMain by getting {
dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation(kotlin("reflect"))
// implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion") <<-- remove this
val jsMain by getting {
dependencies {
implementation(kotlin("stdlib-js"))
// implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion") <<-- remove this
}
}