I have question about HiddenFromObjC. It works per...
# multiplatform
m
I have question about HiddenFromObjC. It works perfectly but it's "kotlin.native" import so it's "red" (unindexed) in Android Studio when target is not set to native (ios) target in Gradle (i.e. Android target on Windows machine). The build itself is ok and not failing. Is this a bug or there is no way to have for example empty "actual" implementation for other target platforms? Thanks.
j
You mean it's "red" in Android Studio? Interestingly for me it is not; just triggers an opt-in warning; and then is fully satisfied when I add also @OptIn(ExperimentalObjCRefinement::*class*) ... But this is on a mac
But why HiddenFromObjC in the first place, can't you just annotate with 'internal'?
m
I have "ExperimentalObjCRefinement" already OptIn in Gradle for all files. So this is not the case afaik. And yes "red" in Android Studio (already on 3 different machines). See attached image. Also "internal" is one way but it needs more work in many areas. Any other idea how to solve it?
j
I suspect it might something missing in your build.gradle.kts, but what exactly, I have no idea 😞 Maybe if you share it here too, either somebody has an idea, or I can check mine for differences?
m
Our gradle config has 20+ files so comparing/sharing is no easy task. But we can try it. Below is the most interesting part about setting up shared codebase. If you find something interesting let me know please.
Copy code
apply(plugin = versionCatalogLibs.findPlugin("multiplatform").get().get().pluginId)
apply(plugin = versionCatalogLibs.findPlugin("android-library").get().get().pluginId)
apply(plugin = versionCatalogLibs.findPlugin("kotlin-parcelize").get().get().pluginId)

configure<KotlinMultiplatformExtension> {

    targets.all {
        compilations.all {
            compilerOptions.configure {
                freeCompilerArgs = listOf(
                    "-Xexpect-actual-classes",
                    "-opt-in=kotlinx.cinterop.ExperimentalForeignApi"
                )
            }
        }
    }

    androidTarget {
        compilations.all {
            kotlinOptions.jvmTarget = versionCatalogLibs.findVersion("java").get().requiredVersion
        }
    }

    if (isIosTargetEnabled()) {
        iosArm64()
        iosSimulatorArm64()
    }

    applyDefaultHierarchyTemplate()

    sourceSets {
        all {
            languageSettings {
                optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
                optIn("kotlin.experimental.ExperimentalObjCName")
                optIn("kotlin.experimental.ExperimentalObjCRefinement")
                optIn("kotlin.RequiresOptIn")
            }
        }

        commonMain {
            kotlin {
                // Add generated resource reference file to sourceSets
                srcDirs(project.projectDir.buildPathForPlatform("common"))
            }

            // Enable simple debugging using Log output for shared projects
            if (!isCiAgent() && isDebugBuildType && project != project(":shared:logging")) {
                dependencies {
                    implementation(project(":shared:logging"))
                }
            }
        }

        androidMain {
            kotlin {
                // Add generated resource reference file to sourceSets
                srcDirs(project.projectDir.buildPathForPlatform("android"))
            }
        }
        val androidDebug by creating
        if (isRcBuildType) {
            val androidRc by creating
        }
        if (isReleaseBuildType) {
            val androidRelease by creating
        }

        if (isIosTargetEnabled()) {
            iosMain {
                kotlin {
                    // Add generated resource reference file to sourceSets
                    srcDirs(project.projectDir.buildPathForPlatform("ios"))
                }
            }
        }
    }
}

configure<LibraryExtension> {

    sourceSets {
        named("main") {
            res.srcDirs(file("${project.projectDir}/src/commonMain/resources"))
        }
    }

    val dataBinding: Boolean? by extra

    buildFeatures {
        // Determines whether to support Data Binding.
        this.dataBinding = dataBinding
    }

    defaultConfig {
        consumerProguardFiles("<http://lib-proguard-rules.pro|lib-proguard-rules.pro>")
    }

    buildTypes {
        create(RC_TYPE)
    }
}

// Register codegen task for our shared resources
tasks.register<ResourcesCodegenTask>(ResourcesCodegenTask.TASK_NAME) {
    projectPath.set(project.projectDir)
    projectName.set(project.name)
}

// Task should run before each build if necessary
tasks.named("preBuild") {
    dependsOn(ResourcesCodegenTask.TASK_NAME)
}

// Task should run on gradle syn if necessary
tasks.named("prepareKotlinIdeaImport") {
    dependsOn(ResourcesCodegenTask.TASK_NAME)
}

if (isIosTargetEnabled()) {
    // Task should run before each ios build if necessary
    tasks.named("compileKotlinIosArm64") {
        dependsOn(ResourcesCodegenTask.TASK_NAME)
    }
    tasks.named("compileKotlinIosSimulatorArm64") {
        dependsOn(ResourcesCodegenTask.TASK_NAME)
    }
}
j
My starts with:
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins {
kotlin("multiplatform")
id("com.android.library")
}
Could that be the difference?
[Because the rest (after the
apply(plugin =
) looks pretty standard to me]
m
We're using VersionCatalog so that include of "multiplatform" plugin can look little bit different. It should be the same multiplatform plugin I hope. I will try to dig into it more.
Message for the future visitors and one solution is below.
HiddenFromObjC
needs to be hidden behind new annotation and typealias. commonMain
expect annotation class HiddenObjC() // custom name
iosMain
actual typealias HiddenObjC = kotlin.native.HiddenFromObjC
androidMain (or other non-native platform)
actual annotation class HiddenObjC()