Hey guys, does anybody use `moko` with KMM and iOS...
# ios
e
Hey guys, does anybody use
moko
with KMM and iOS? I have this issue https://kotlinlang.slack.com/archives/C3PQML5NU/p1702841258546119 and will appreciate any help
i
Did you apply the moko plugin on the project that creates the iOS framework? Is your framework static or dynamic?
e
@iXPert12 Originally it was a project generated by Kotlin Multiplatform Wizard. I just implemented one screen with Compose in the common module and added moko for resources. This is my grade config:
Copy code
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractExecutable
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBinary
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
import org.jetbrains.kotlin.library.impl.KotlinLibraryLayoutImpl
import java.io.File
import java.io.FileFilter
import org.jetbrains.kotlin.konan.file.File as KonanFile

plugins {
    alias(libs.plugins.kotlinMultiplatform)
    alias(libs.plugins.androidApplication)
    alias(libs.plugins.jetbrainsCompose)

    id("dev.icerock.mobile.multiplatform-resources")
}

kotlin {
    targetHierarchy.default()      // <https://github.com/icerockdev/moko-resources/issues/383>

    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = "1.8"
            }
        }
    }

    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "ComposeApp"
            isStatic = true
        }
    }

    sourceSets {

        androidMain {
            dependsOn(commonMain.get())

            kotlin.srcDir("build/generated/moko/androidMain/src")

            dependencies {
                implementation(libs.compose.ui.tooling.preview)
                implementation(libs.androidx.activity.compose)
            }
        }

        commonMain.dependencies {
            implementation(compose.runtime)
            implementation(compose.foundation)
            implementation(compose.material3)
            implementation(compose.ui)

//            @OptIn(ExperimentalComposeLibrary::class)
//            implementation(compose.components.resources)

            api(libs.moko.resources)
            api(libs.moko.resources.compose) // for compose multiplatform

//            testImplementation("dev.icerock.moko:resources-test:0.23.0")
        }
    }
}

android {
    namespace = "com.tagbeam"
    compileSdk = libs.versions.compileSdkVersion.get().toInt()

    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    sourceSets["main"].res.srcDirs("src/androidMain/res")
    sourceSets["main"].resources.srcDirs("src/commonMain/resources")

    defaultConfig {
        applicationId = "com.tagbeam"
        minSdk = libs.versions.minSdkVersion.get().toInt()
        targetSdk = libs.versions.targetSdkVersion.get().toInt()
        versionCode = 1
        versionName = "1.0"
    }
    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    dependencies {
        debugImplementation(libs.compose.ui.tooling)
    }
}

multiplatformResources {
    multiplatformResourcesPackage = "com.tagbeam" // required
//    multiplatformResourcesClassName = "Res" // optional, default MR
//    multiplatformResourcesVisibility = MRVisibility.Internal // optional, default Public
    iosBaseLocalizationRegion = "en" // optional, default "en"
//    multiplatformResourcesSourceSet = "commonClientMain"  // optional, default "commonMain"
}
I am using Kotlin 1.9.20
i
There is an ongoing issue with moko and kotlin 1.9.0 and up. The safest bet is to downgrade to 1.8.22
e
@iXPert12 I tried to do that, but I got several errors in the gradle config:
It looks like gradle configuration structure also depends on this kotlin version because the multiplatform plugin also uses it.
i
rename androidTarget to android
e
@iXPert12 now I get another error:
Copy code
Build file '/Users/electrolobzik/workspace/Projects/15SecOfFame/App/TagBeam/composeApp/build.gradle.kts' line: 21

Build was configured to prefer settings repositories over project repositories but repository 'ivy' was added by build file 'composeApp/build.gradle.kts'
the line 21 is this one:
Copy code
listOf(
>>>     iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "ComposeApp"
            isStatic = true
        }
    }
this is the full config:
Copy code
plugins {
    alias(libs.plugins.kotlinMultiplatform)
    alias(libs.plugins.androidApplication)
    alias(libs.plugins.jetbrainsCompose)

    id("dev.icerock.mobile.multiplatform-resources")
}

kotlin {
    targetHierarchy.default()      // <https://github.com/icerockdev/moko-resources/issues/383>

    android {
        compilations.all {
            kotlinOptions {
                jvmTarget = "1.8"
            }
        }
    }

    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "ComposeApp"
            isStatic = true
        }
    }

    sourceSets {

        android {
//            dependsOn(commonMain.get())

//            kotlin.srcDir("build/generated/moko/androidMain/src")

            dependencies {
                implementation(libs.compose.ui.tooling.preview)
                implementation(libs.androidx.activity.compose)
            }
        }

        commonMain {
            dependencies {
                implementation(compose.runtime)
                implementation(compose.foundation)
                implementation(compose.material3)
                implementation(compose.ui)

//            @OptIn(ExperimentalComposeLibrary::class)
//            implementation(compose.components.resources)

                api(libs.moko.resources)
                api(libs.moko.resources.compose) // for compose multiplatform

//            testImplementation("dev.icerock.moko:resources-test:0.23.0")
            }
        }
    }
}

android {
    namespace = "com.tagbeam"
    compileSdk = libs.versions.compileSdkVersion.get().toInt()

    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    sourceSets["main"].res.srcDirs("src/androidMain/res")
    sourceSets["main"].resources.srcDirs("src/commonMain/resources")

    defaultConfig {
        applicationId = "com.tagbeam"
        minSdk = libs.versions.minSdkVersion.get().toInt()
        targetSdk = libs.versions.targetSdkVersion.get().toInt()
        versionCode = 1
        versionName = "1.0"
    }
    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    dependencies {
        debugImplementation(libs.compose.ui.tooling)
    }
}

multiplatformResources {
    multiplatformResourcesPackage = "com.tagbeam" // required
//    multiplatformResourcesClassName = "Res" // optional, default MR
//    multiplatformResourcesVisibility = MRVisibility.Internal // optional, default Public
    iosBaseLocalizationRegion = "en" // optional, default "en"
//    multiplatformResourcesSourceSet = "commonClientMain"  // optional, default "commonMain"
}
@iXPert12 I managed to run the project (changed repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)) but I still get the same error on iOS:
Copy code
Uncaught Kotlin exception: kotlin.IllegalArgumentException: bundle with identifier <http://com.tagbeam.MR|com.tagbeam.MR> not found
i
also, set isStatic to false
ok, i would suggest to try the template before updating to kotlin 1.9 https://github.com/JetBrains/compose-multiplatform-template/tree/84b90dd3497aa8b53fb7493a08fc916f9b01ed57
e
@iXPert12 what does the
isStatic
setting do and do you know why it is turned on by default in the Wizard project? As I see from documentation it is false by default since Kotlin 1.8.0. Is this Template in the link newer/updated than the project from the KMM Wizard?
i
it is about how the ios framework will be linked. By default moko resources support dynamic linking without any other modifications required. If you need static linking, there are some additional tasks to be done.https://github.com/icerockdev/moko-resources#with-orgjetbrainskotlinnativecocoapods
e
@iXPert12 why someone may want to use static instead of dynamic?
@iXPert12 If I set isStatic=false I get this error:
Copy code
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors

The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1.
output:
ld: unknown options: -ios_simulator_version_min -sdk_version 
error: Compilation finished with errors
i
this is an issue with latest xcode. Please remove it, and install Xcode 14.2