0

I followed the Targeting iOS and Android with Kotlin Multiplatform tutorial and was able to setup the working project for both ios and android.

As a next step I want to use android specific libs inside src/androidMain/. Example:

package com.test.android

import android.os.Build

actual fun getBuildInfo(): String {
  return Build.MODEL
}

But for the import I receive: Unresolved reverence: os

Question: Which additional steps are needed to use android specific libs inside androidMain?


The: build.gradle.kts

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

plugins {
    kotlin("multiplatform")
}

kotlin {
    //select iOS target platform depending on the Xcode environment variables
    val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
        if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
            ::iosArm64
        else
            ::iosX64

    iOSTarget("ios") {
        binaries {
            framework {
                baseName = "multi_module_be_connection"
            }
        }
    }

    jvm("android")

    sourceSets["commonMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
    }

    sourceSets["androidMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib")
    }
}

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 framework = kotlin.targets
        .getByName<KotlinNativeTarget>("ios")
        .binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)

    from({ framework.outputDirectory })
    into(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.getByName("build").dependsOn(packForXcode)

Source of the project is here: https://github.com/kotlin-hands-on/mpp-ios-android

1 Answer 1

2

In order to make use of android specific API in a MPP module you can include the android lib plugin:

The: build.gradle.kts

plugins {
    id("com.android.library")
    kotlin("multiplatform")
}

When doing so it's mandatory to include an AndroidManifest.xml, this can be placed in your src/androidMain/ and by including it in your script for the android build with:

The: build.gradle.kts

android {

    sourceSets {
        getByName("main") {
            manifest.srcFile ("src/androidMain/AndroidManifest.xml")
        }
    }

}

The: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest package="org.path.to.package.common"/>

NOTE: change the package path.

Sign up to request clarification or add additional context in comments.

2 Comments

I also had to replace jvm("android") with android("android"). Can you explain why?
Ah yes, you can also write it in the more DSL styled way: android { }. I'm not an expert on the plugin but I suspect since this is usually an Android specific plugin it only looks for the android block for build configuration as mentioned in the docs

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.