Kotlin Multiplatform Library: Unable to generate .framework for iOS

3.5k Views Asked by At

I am new to Android/KotlinMultiplatform , I am trying to create a library for iOS/Android using Kotlin Multiplatform.

When I run the command on terminal ./gradlew :shared:packForXcode It succeeds but could not find a /build/xcode-frameworks folder inside the root folder.

Could anyone help me to find where it is going wrong...?

IntelliJ CE Version : 2020.2.3

My Gradle file Content:

plugins {
    id("org.jetbrains.kotlin.multiplatform") version "1.4.10"
    id("com.android.library")
    id("kotlin-android-extensions")
    "maven-publish"
}
repositories {
    mavenCentral()
}

group "me.myname"
version "0.0.1"

kotlin {
    targets {
        android()
        ios {
            binaries {
                framework {
                    baseName = "MyLib"
                }
            }
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9")
            }
        }
        val androidMain by getting {
            dependencies { }
        }
        val iosMain by getting {
            dependencies { }
        }
    }

}

android {
    compileSdkVersion(29)
    defaultConfig {
        minSdkVersion(24)
        targetSdkVersion(29)
        versionCode = 1
        versionName = "1.0"
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
        }
    }
}

val packForXcode by tasks.creating(Sync::class) {
    val targetDir = File(buildDir, "xcode-frameworks")

    /// selecting the right configuration for the iOS
    /// framework depending on the environment
    /// variables set by Xcode build
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val sdkName: String? = System.getenv("SDK_NAME")
    val isiOSDevice = sdkName.orEmpty().startsWith("iphoneos")

    val framework = kotlin.targets
        .getByName<KotlinNativeTarget>(
            if(isiOSDevice) {
                "iosArm64"
            } else {
                "iosX64"
            }
        )
        .binaries.getFramework(mode)

    inputs.property("mode", mode)
    dependsOn(framework.linkTask)

    from({ framework.outputDirectory })
    into(targetDir)

    println("Build Folder => $targetDir")

    /// generate a helpful ./gradlew wrapper with embedded Java path
    doLast {
        val gradlew = File(targetDir, "gradlew")
        gradlew.writeText("#!/bin/bash\n"
                + "export 'JAVA_HOME=${System.getProperty("java.home")}'\n"
                + "cd '${rootProject.rootDir}'\n"
                + "./gradlew \$@\n")
        gradlew.setExecutable(true)
    }
}

tasks.build.dependsOn("packForXCode")

UPDATE

  1. Project Created using IntelliJ IDEA, as below screenshot:

enter image description here

  1. My project structure looks like below:

enter image description here

2

There are 2 best solutions below

1
On BEST ANSWER

I've only been able to see the template of your screenshot by using

IntelliJ 2020.2.3 Ultimate

This template doesn't have the packForXcode task set by default, so you would have put it by hands I suppose.

Anyway, with a cleaned project, if you run it, you could have the debug framework in the build folder where you want to have it.

enter image description here

You should have, of course, at least one source (Greeting.kt) file like the one I've shown you in my pic.

I suggest you to look deep at the documentation starting from here and here.

7
On

If I remember correctly, this task is not designed to be executed manually. It should be triggered as a part of the Xcode project build, see in the documentation. Please try to follow the steps from the documentation, and see if the framework connects and works fine from Xcode.