Skip to content

Latest commit

 

History

History
123 lines (87 loc) · 5.26 KB

README.md

File metadata and controls

123 lines (87 loc) · 5.26 KB

Kotlin Multiplatform

The Kotlin Multiplatform (KMP) technology facilitates the sharing of application code across several platforms.

Table of Contents

Architecture Overview

The KMP architecture is composed of three main categories:

  • Common: Code shared across all platforms (i.e., CommonMain, CommonTest);
  • Intermediary: Code that can be shared on a particular set of platforms. See Intermediate Source Sets;
  • Specific: Platform-specific code (i.e., <Platform>Main, <Platform>Test).

The main goal is to maximize code reuse, meaning to aggregate as much code as possible in the Common category. However, sometimes it's necessary to create specific code for a target platform in the following situations:

  1. A certain functionality cannot be implemented commonly because:

    • It requires access to specific target APIs;
    • The libraries available for common code (i.e., Standard Kotlin Library, Kotlinx) do not cover the desired functionalities, and there's no external KMP-compatible library available to be used as a dependency (or it is discouraged to use);
  2. A certain target does not directly support KMP (e.g., Node.js), and thus an adapter is needed for the code to be callable from the target.

To create specific code for a target, the expect/actual mechanism is used, which allows defining the code to be implemented and its target or sub-target implementation, respectively.

Example:

// commonMain
expect fun platformName(): String

// jvmMain
actual fun platformName(): String = "JVM"

// jsMain
actual fun platformName(): String = "JS"
KMP Architecture
KMP Architecture Overview

Testing the Application

In the KMP template provided by Kotlin, the example with the fibonacci sequence was removed and replaced by a few examples to practice the expect/actual mechanism more thoroughly.

This addition follows the same principles:

  • test common functionality in CommonTest;
  • test platform-specific functionality in each platform's test source set (<Platform>Test)

To run the tests for all supported targets, use the command:

# from root or within a run configuration 
./gradlew :kmp:lib:cleanAllTests :kmp:lib:allTests --rerun-tasks

Intermediate Source Sets

Intermediate Source Sets enable sharing code across a subset of platforms, allowing for more flexibility in the code sharing strategy.

Intermediate Source Set
Intermediate Source Set Example

In the corresponding build.gradle.kts file, the dependencies between source sets can be configured manually or by using applyDefaultHierarchyTemplate() which builds the hierarchy of the provided targets automatically.

Important

Both iOS and macOs source sets were removed from this build, because there is no macOS x86-64 host available for testing, as required by Apple.

Adapter

The adapter is a module that allows code defined in a KMP project to be called from a target that does not directly support KMP and Kotlin in general.

For demonstration purposes, a pure JS application was created to call the adapter defined in the JsMain sorceset, essentially acting as a consumer.

To run the application:

  1. Execute the perl script to link local npm packages in this project.
  2. Run the server:
    node kmp/apps/js-app/src/server.mjs
    # take a look at the express paths and PORT configured in the server
    # open an HTTP client and access http://localhost:PORT

For more information about Kotlin and JavaScript interop, see Kotlin-Js Interop section.

Relevant Design Choices

As mentioned in this issue, the expect/actual pattern should only be used for functions and interfaces. An alternative for this pattern is to use expect fun + interface in the common module.

KT-61573
KT-61573