Calling native iOS / Android methods from Kotlin Multiplatform

#1

Hi,
I understand that I can call shared KMP code from both the ‘host’ android or iOS app, but
can I have my shared KMP code call android/iOS methods?
i.e. the shared code runs a computation at the end its calls a “callback” which is implemented differently on the specific platfrom (android/ios) layer.

#2

Take a look at expect/actual keywords:
https://kotlinlang.org/docs/reference/multiplatform.html#how-it-works

#3

But how do you actually call an Android API? The tutorial shows you can import platform.UIKit.UIDevice. That works, great.

What about import platform.android.graphics.Bitmap? Or anything from android. Trying that gives me Unresolved reference: android.

Here’s my build.gradle:

apply plugin: 'kotlin-multiplatform'
apply plugin: 'kotlinx-serialization'

repositories {
    jcenter()
}

def ktor_version = "1.1.4"

kotlin {
    targets {
        final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
                              ? presets.iosArm64 : presets.iosX64

        fromPreset(iOSTarget, 'ios') {
            binaries {
                framework('SharedCode') {
                    embedBitcode "bitcode"
                }
            }
        }

        fromPreset(presets.jvm, 'android')
    }

    sourceSets {
        commonMain.dependencies {
            implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.0"
            implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.11.0"
            implementation "io.ktor:ktor-client-core:$ktor_version"
            implementation "io.ktor:ktor-client-cio:$ktor_version"
            implementation "io.ktor:ktor-client-json:$ktor_version"
            api 'org.jetbrains.kotlin:kotlin-stdlib-common'
        }

        androidMain.dependencies {

            api 'org.jetbrains.kotlin:kotlin-stdlib'
        }
    }
}

// workaround for https://youtrack.jetbrains.com/issue/KT-27170
configurations {
    compileClasspath
}

task packForXCode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")
    final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
    final def framework = kotlin.targets.ios.binaries.getFramework("SharedCode", mode)

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

    from { framework.outputFile.parentFile }
    into frameworkDir

    doLast {
        new File(frameworkDir, 'gradlew').with {
            text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
            setExecutable(true)
        }
    }
}
tasks.build.dependsOn packForXCode
#4

(I’m trying to import platform.android.graphics.Bitmap from the androidMain/kotlin/ directory described in the tutorial)