I'm trying to make a Kotlin Multiplatform library to be used in both Android, JavaScript and iOS. This library is composed of multiple modules so that it can be easily extensible. My problem right now is only with Kotlin native.
This is how the project is setup
- A module
:common
object MySingleton {
fun doSomethingWithMyInterface(value: MyInterface) {
// ...
}
}
interface MyInterface {
fun doSomething()
}
- Other modules implementing
MyInterface
class MyInterfaceExample : MyInterface {
override fun doSomething() {
// ...
}
}
I have setup the build.gradle.kts
file for :common
as follow:
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
id("maven-publish")
}
kotlin {
targets {
jvm()
js().browser()
ios("ios") {
binaries {
framework("CommonModule") {
baseName = "common"
}
}
}
}
cocoapods {
frameworkName = "CommonModule"
summary = "My common module"
homepage = "-"
license = "-"
ios.deploymentTarget = "10.0"
}
sourceSets {
val iosX64Main by getting
val iosArm64Main by getting
val iosMain by getting {
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
}
}
}
And my other module as follow:
plugins {
id("com.android.library")
id("maven-publish")
kotlin("multiplatform")
kotlin("native.cocoapods")
}
android {
compileSdkVersion(30)
}
kotlin {
targets {
js().browser()
ios("ios") {
binaries {
framework("ExampleImplementation", listOf(DEBUG)) {
baseName = "example"
freeCompilerArgs += "-Xobjc-generics"
export(project(":common")) {
isStatic = true
}
}
}
}
android("android") {
publishLibraryVariants("release")
}
}
cocoapods {
frameworkName = "ExampleImplementation"
summary = "Example implementation of MyInterface"
homepage = "-"
license = "-"
useLibraries()
ios.deploymentTarget = "10.0"
pod("MyDependency")
}
sourceSets {
val commonMain by getting {
dependencies {
api(project(":common"))
}
}
val iosX64Main by getting
val iosArm64Main by getting
val iosMain by getting {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
}
val androidMain by getting {
dependsOn(commonMain)
dependencies {
implementation("group:artifactId:1.0.0")
}
}
val jsMain by getting {
dependencies {
implementation(npm("my_dependency", "1.0.0"))
}
}
}
}
Both :common
and :example
modules generate a podspec
file which adds a script to be executed by cocoapods manager:
<<-SCRIPT
set -ev
REPO_ROOT="$PODS_TARGET_SRCROOT"
"$REPO_ROOT/../gradlew" -p "$REPO_ROOT" :example:syncFramework \
-Pkotlin.native.cocoapods.target=$KOTLIN_TARGET \
-Pkotlin.native.cocoapods.configuration=$CONFIGURATION \
-Pkotlin.native.cocoapods.cflags="$OTHER_CFLAGS" \
-Pkotlin.native.cocoapods.paths.headers="$HEADER_SEARCH_PATHS" \
-Pkotlin.native.cocoapods.paths.frameworks="$FRAMEWORK_SEARCH_PATHS"
SCRIPT
When I add those modules in an iOS project like so:
pod 'common', :path => '~/Project/MyLibrary/common/'
pod 'example', :path => '~/Project/MyLibrary/example/'
After I do a pod install
, I can see both frameworks being added.
The problem
The framework generated for example
doesn't depend on the framework generated for common
. Yet, :example
generates an interface of its own called ExampleCommonMyInterface
which have the same signature as MyInterface
in :common
.
Also, both of them includes some KotlinBase
classes which prevents me from building as I encounter an issue for duplicated classes.
I tried to only include :example
but then it's missing my MySingleton
class (which is not a Singleton in Swift but that's another issue) and other classes which :example
doesn't depend on directly.
Also, at some point, I would like to have more than one module depending on :common
so only including :example
would only work temporarily.
I have tried many things for several days now but none of them works. Also, the documentation is scattered between the documentation for kotlin multiplatform and kotlin native which made it hard for me to find relevant information regarding what I'm trying to achieve.
I understand that Kotlin multiplatform is still not stable and what I'm trying to achieve may not be possible at the moment. Nevertheless, I would greatly appreciate if someone can shed some light on what the problem is and how I can solve it.