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

MMG
  • 3,226
  • 5
  • 16
  • 43
IIIIIIIIIIIIIIIIIIIIII
  • 3,958
  • 5
  • 45
  • 70

1 Answers1

1

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.

Lucho
  • 1,455
  • 1
  • 13
  • 25
  • I also had to replace `jvm("android")` with `android("android")`. Can you explain why? – IIIIIIIIIIIIIIIIIIIIII May 04 '20 at 16:18
  • 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](https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.LibraryExtension.html) – Lucho May 04 '20 at 17:20