Search code examples
xcodekotlinbuild.gradlekotlin-multiplatformkotlin-multiplatform-mobile

Error to compile ios project with kotlin multiplatform


I have implemented kotlin multiplatform in an existing ios project and I have these problems

When I compile the application for the simulator an error occurs in the build phases script.

enter image description here

enter image description here

Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain
Caused by: java.lang.ClassNotFoundException: org.gradle.wrapper.GradleWrapperMain
Command PhaseScriptExecution failed with a nonzero exit code

When I remove the script the compiled for simulator works 🤔. I can run the simulator

Another error is when I want to archive the project. Says it was built for iOS simulator 🤯

enter image description here

My build.gradle.kts

import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget

plugins {
    kotlin("multiplatform")
    kotlin("native.cocoapods")
    kotlin("plugin.serialization")
    id("com.android.library")
    id("kotlin-android-extensions")
    id("com.squareup.sqldelight")
}

repositories {
    gradlePluginPortal()
    google()
    jcenter()
    mavenCentral()
    maven {
        url = uri("https://dl.bintray.com/kotlin/kotlin-eap")
    }
}

dependencies {
    implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.2.0")
}

configurations {
    create("compileClasspath")
}

android {
    compileSdkVersion(29)
    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    defaultConfig {
        minSdkVersion(24)
        targetSdkVersion(29)
        versionCode = 1
        versionName = "1.0"
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
        }
    }
}

val libName = "shared"

kotlin {
    android()
    ios {
        binaries.framework(libName)
    }

    val coroutinesVersion = "1.4.1-native-mt"
    val serializationVersion = "1.0.0-RC"
    val ktorVersion = "1.4.0"
    val sqlDelightVersion = "1.4.3"
    val reactive_version = "1.1.18"

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib-common")

                // Coroutines
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.3.2")

                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serializationVersion")

                //  KTOR
                implementation("io.ktor:ktor-client-core:$ktorVersion")
                implementation("io.ktor:ktor-client-json:$ktorVersion")
                implementation("io.ktor:ktor-client-serialization:$ktorVersion")

                // SQLDELIGHT
                implementation("com.squareup.sqldelight:runtime:$sqlDelightVersion")

                // Reactive
                implementation("com.badoo.reaktive:reaktive:$reactive_version")
            }
        }
        val androidMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib")

                implementation("androidx.core:core-ktx:1.3.2")
                implementation("io.ktor:ktor-client-android:$ktorVersion")
                implementation("com.squareup.sqldelight:android-driver:$sqlDelightVersion")

                implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
            }
        }
        val iosMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-native:1.3.2")

                // HTTP
                implementation("io.ktor:ktor-client-ios:$ktorVersion")
                implementation("com.squareup.sqldelight:native-driver:$sqlDelightVersion")
            }
        }

        all {
            languageSettings.apply {
                progressiveMode = true
                useExperimentalAnnotation("kotlin.RequiresOptIn")
                useExperimentalAnnotation("kotlinx.coroutines.ExperimentalCoroutinesApi")
            }
        }
    }
}

val packForXcode by tasks.creating(Sync::class) {
    group = "build"
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
    val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
    val framework = kotlin.targets.getByName<KotlinNativeTarget>(targetName).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)

sqldelight {
    database("SmileduDataBase") {
        packageName = "com.example.smiledu"
        schemaOutputDirectory = file("src/commonMain/db/databases")
    }
}

Solution

  • Another error is when I want to archive the project. Says it was built for iOS simulator 🤯
    

    Hi. I faced this issue a few times and the only work around I got is that we need to run this ./gradlew clean in android studio terminal before creating an archive for iOS and then try to create archive and it should work. You can find more details on this here :- https://youtrack.jetbrains.com/issue/KT-40907

    When I compile the application for the simulator an error occurs in the build phases script.
    

    For this it looks like your wrapper is corrupted probably am not so sure about this. Does android app runs perfectly ? Also you can have a look here once :- How to resolve java.lang.ClassNotFoundException: org.gradle.wrapper.GradleWrapperMain error?