KMM & KMP share business logic with react app - kotlin

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

Related

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

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()}!"
}
}

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
}
}

androidMain and android tests folder not recognised as module

I’ve been struggling with this issue since days but can’t find any solution so I hope I can get any help here.
I created a Multiplatform project with Mobile Application template from IntelliJ IDEA 2020.2.1 and since project setup androidMain and AndroidTest folders are not recognised as module. This seems not to be a problem when launching androidApp task or PackForXcode as references to expect/actual definitions are resolved but idea suggestions shows anyway how androidMain reference seems to be wrong as reference seems to be resolved from parent vpayConnectLib module as per screenshot.
I use a standard android() target
When launching compileDebugAndroidTestKotlinAndroid task this error is highlighted
I tried to create new projects with different templates but androidMain and androidTest folders are not considered module since the beginning with all projects template
Is this a know bug or I am doing something wrong? Here’s root project gradle file with versions I am using
Hre's my root project gradle file:
buildscript {
repositories {
gradlePluginPortal()
jcenter()
google()
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0")
classpath("com.android.tools.build:gradle:4.0.1")
classpath("com.squareup.sqldelight:gradle-plugin:1.4.3")
classpath("org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8")
}
}
group = "com.retailinmotion"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
and here's shared library gradle file
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins {
kotlin("multiplatform")
id("com.android.library")
id("kotlin-android-extensions")
id("com.squareup.sqldelight")
id("org.sonarqube")
jacoco
}
group = "com.retailinmotion"
version = "1.0-SNAPSHOT"
repositories {
gradlePluginPortal()
google()
jcenter()
mavenCentral()
}
sqldelight {
database("vPayConnectDatabase") {
packageName = "com.retailinmotion.vpayconnect"
sourceFolders = listOf("sqldelight")
}
}
task<JacocoReport>("jacocoTestReport") {
dependsOn("testDebugUnitTest")
reports {
xml.isEnabled = true
csv.isEnabled = false
html.isEnabled = true
}
sourceDirectories.setFrom(files(fileTree("../vPayConnectLib")))
classDirectories.setFrom(files(fileTree("build/tmp/kotlin-classes/debug")))
executionData.setFrom(file("build/jacoco/testDebugUnitTest.exec"))
}
sonarqube {
properties {
property("sonar.sourceEncoding", "UTF-8")
property("sonar.java.coveragePlugin", "jacoco")
property("sonar.sources", "src/commonMain/kotlin, src/iosMain/kotlin, src/androidMain/kotlin")
property("sonar.tests", "src/commonTest/kotlin, src/iosTest/kotlin, src/androidTest/kotlin")
property("sonar.binaries", "build/tmp/kotlin-classes/debug")
property("sonar.java.binaries", "build/tmp/kotlin-classes/debug")
property("sonar.java.test.binaries", "build/tmp/kotlin-classes/debugUnitTest")
property("sonar.junit.reportPaths", "build/test-results/testDebugUnitTest")
property("sonar.jacoco.reportPaths", "build/jacoco/testDebugUnitTest.exec")
property("sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml")
}
}
kotlin {
android()
iosArm64("ios") {
binaries {
framework {
baseName = "vPayConnectLib"
}
}
compilations["main"].cinterops {
//import Datecs library
val datecs by creating {
packageName ("com.retailinmotion.datecs")
defFile = file("$projectDir/src/iosMain/c_interop/Datecs.def")
includeDirs ("$projectDir/src/iosMain/c_interop/Datecs/")
}
//import Datecs Utils library
val datecsutils by creating {
packageName ("com.retailinmotion.datecsutils")
defFile = file("$projectDir/src/iosMain/c_interop/DatecsUtils.def")
includeDirs ("$projectDir/src/iosMain/c_interop/DatecsUtils/")
}
//import Magtek library
val magtek by creating {
packageName ("com.retailinmotion.magtek")
defFile = file("$projectDir/src/iosMain/c_interop/Magtek.def")
includeDirs ("$projectDir/src/iosMain/c_interop/Magtek")
}
}
}
iosX64(){
binaries {
framework {
baseName = "vPayConnectLib"
}
}
compilations["main"].cinterops {
//import Datecs library
val datecs by creating {
packageName ("com.retailinmotion.datecs")
defFile = file("$projectDir/src/iosMain/c_interop/Datecs.def")
includeDirs ("$projectDir/src/iosMain/c_interop/Datecs/")
}
//import Datecs Utils library
val datecsutils by creating {
packageName ("com.retailinmotion.datecsutils")
defFile = file("$projectDir/src/iosMain/c_interop/DatecsUtils.def")
includeDirs ("$projectDir/src/iosMain/c_interop/DatecsUtils/")
}
//import Magtek library
val magtek by creating {
packageName ("com.retailinmotion.magtek")
defFile = file("$projectDir/src/iosMain/c_interop/Magtek.def")
includeDirs ("$projectDir/src/iosMain/c_interop/Magtek")
}
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("com.squareup.sqldelight:runtime:1.4.3")
}
}
val commonTest by getting {
dependsOn(commonMain)
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
implementation("org.jetbrains.kotlin:kotlin-test-junit:1.4.10")
}
}
val androidMain by getting {
dependencies {
implementation("androidx.core:core-ktx:1.3.1")
implementation("com.squareup.sqldelight:android-driver:1.4.3")
}
}
val androidTest by getting {
dependsOn(androidMain)
}
val iosMain by getting {
dependencies {
implementation("com.squareup.sqldelight:native-driver:1.4.3")
}
}
val iosTest by getting {
dependsOn(iosMain)
}
val iosX64Main by getting {
dependsOn(iosMain)
}
val iosX64Test by getting {
dependsOn(iosTest)
}
}
tasks {
register("universalFramework", org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask::class) {
val debugMode = "DEBUG"
val mode = System.getenv("CONFIGURATION") ?: debugMode
baseName = "vPayConnectLib"
val iosArm64Framework = iosArm64("ios").binaries.getFramework(mode)
val iosX64Framework = iosX64().binaries.getFramework(mode)
from(
iosArm64Framework,
iosX64Framework
)
destinationDir = buildDir.resolve("xcode-universal-framework")
group = "Universal framework"
description = "Builds a universal (fat) $mode framework"
dependsOn(iosArm64Framework.linkTask)
dependsOn(iosX64Framework.linkTask)
}
}
}
android {
compileSdkVersion(29)
defaultConfig {
minSdkVersion(24)
targetSdkVersion(29)
versionCode = 1
versionName = "1.0"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}
}
val packForXcode by tasks.creating(Sync::class) {
group = "build"
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val framework = kotlin.targets.getByName<KotlinNativeTarget>("ios").binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
val targetDir = File(buildDir, "xcode-frameworks")
from({ framework.outputDirectory })
into(targetDir)
}
tasks.getByName("build").dependsOn(packForXcode)
Any help is appreciated,
Thanks