Home > Net >  How to implement custom platform logic using Kotlin Multiplatform feature?
How to implement custom platform logic using Kotlin Multiplatform feature?

Time:04-04

Kotlin Multiplatform is a good feature to build multiplatform applications, but currently it is (likely) restricted to be intrinsic in Kotlin Multiplatform ecosystem. Can I implement custom build logic to extend the resolution strategy of expect, actual and the like? Or to say treat these features as a general concept of multiplatform, but have different behaviors during build process. Gradle work is welcomed.

For example, if the related extension points were available, one could write a Kotlin compiler plugin to resolve those expect/actual endpoints and maybe compose them into actually platform-specific runtime logic, and then write a Gradle plugin to ultimately process these artifacts.

So if there were two "multiplatform" scenes where both use jvm as "backend", but provide different api with the same or similar logic as "frontend", one could do as above to provide benefits which Kotlin Multiplatform does - write once, run anywhere.

I'd prefer to call this "api-layer multiplatform", to differ that Kotlin Multiplatform is "system-layer multiplatform". "Platform" could be a more abstract one.

So here is what the producer does, just like Kotlin Multiplatform:

build.gradle.kts:

plugins {
    kotlin("jvm")
    id("<multiplatform-plugin-id>") // Comes with Kotlin compiler plugin too
}

dependencies {
    api("<common-dependency-notation>") // Another multiplatform library
}

common module:

fun hello() {
    val logger = serviceLogger // Using api from that another multiplatform library
    logger.info("Hello")
}

expect fun hookOnStart(block: () -> Unit) // Needs to provide platform-specific implementations

platform module:

actual fun hookOnStart(block: () -> Unit) { // Imaginary
    ClientEvents.START.register(block)
}

anotherPlatform module:

actual fun hookOnStart(block: () -> Unit) { // Imaginary
    val event = EventFactory.once(ClientStartEvent::class.java, block)
    GlobalEventHandler.register(event)
}

As said before, after build, each platform will have its own artifact prepared for runtime or provided as library. He benefits from that another multiplatform library because he could provide each platform with same features through sharing code.

And the following is what the consumer does: (Let's say he's on platform)

build.gradle.kts

plugins {
    kotlin("jvm")
}

dependencies {
    implementation("<previous-common-dependency-notation>") // From the previous author, mapped to `platform` version
}

Bussiness logic:

fun runBussiness() {
    hello()
    hookOnStart { serviceLogger.info("world!") }
}

CodePudding user response:

This is pretty uncharted territory and without any documentation.

I'd investigate the source code of the kotlin-multiplatform gradle plugin more in-depth, see if you can extend the existing target palette and expect/actual behaviour.

I'd guess that the plugin isn't really built for this kind of extension, but if you have solid reasons, you could probably submit feature requests and work on a local fork in the meantime.

  • Related