Kotlin Multiplatform: Can't reference class in commonMain sourceset from another module's androidMain sourceset

2k Views Asked by At

I have two multiplatform modules shared and other in a standard multiplatform template project that targets Android and iOS.

shared defines a class in commonMain source set

class SharedGreeting()

other is setup to depend on shared like this in the gradle file:

val commonMain by getting {
            dependencies {
                implementation(project(":shared"))
            }
        }

And in its androidMain sourceset it tries to reference SharedGreeting in some class, fx:

class AndroidGreeter{
   val foo = SharedGreeting()
}

But no matter what I try, I get IDE errors when I try to reference the shared class, and I have to manually add an import statement.

The code compiles and deploys without problems though! Any ideas on what I am missing or misunderstanding? Or is this a bug in KMM?

Full copy of other gradle file:

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 = "other"
        }
    }
    
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation(project(":shared"))
            }
        }
        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 = 24
        targetSdk = 32
    }
}

For full project source code: https://github.com/RabieJradi/kmm_import_error_sample

IDE suggested action for adding a dependency doesn't unfortunately do anything. enter image description here

2

There are 2 best solutions below

0
Rabie Jradi On BEST ANSWER
2
Dave M. On

You cannot do this in that way.

To make your project work you have to work with expect and actual words.

So, make these changes:

change your SharedGreeting class in shared module like that:

expect class SharedGreeting {
    fun greeting(): String
}

Then your IDE wants you to make two changes, in shared module. Add a class in both modules, iosMain and androidMain named SharedGreeting. The code is the same for both classes:

actual class SharedGreeting {
    actual fun greeting(): String {
        return "Hello, ${Platform().platform}!"
    }
}

The work is done, now your other library has no errors. From your androidMain module inside "other" you can work only on other androidMain modules inside other MKK libraries.