https://kotlinlang.org logo
#moko
Title
# moko
j

Julius

12/02/2020, 5:01 PM
Hello, I'm currently trying to implement the moko-resources but I keep receiving the gradle error: Required value was null.
root build.gradle.kts
Copy code
buildscript {
    repositories {
        gradlePluginPortal()
        jcenter()
        google()
        mavenCentral()
        maven(url = "<https://dl.bintray.com/icerockdev/plugins>")
    }
    dependencies {
        classpath("com.android.tools.build:gradle:${Deps.Version.gradle}")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Deps.Version.kotlin}")
        classpath("org.jetbrains.kotlin:kotlin-serialization:${Deps.Version.kotlin}")
        classpath("com.squareup.sqldelight:gradle-plugin:${Deps.Version.sqlDelight}")
        classpath("dev.icerock.moko:resources-generator:${Deps.Version.mokoResources}")

        classpath("com.google.gms:google-services:4.3.4")
    }
}

repositories {
    jcenter()
    google()
    mavenCentral()
    maven(url = "<https://jitpack.io>")
    maven(url = "<https://dl.bintray.com/icerockdev/moko>")

    flatDir {
        dirs("libs/compile")
    }
}

task<Delete>("clean") {
    delete(rootProject.buildDir)
}
shared build.gradle.kts
Copy code
plugins {
    plugin(Deps.Plugins.kotlinMultiplatform)
    plugin(Deps.Plugins.kotlinSerialization)
    plugin(Deps.Plugins.androidLibrary)
    plugin(Deps.Plugins.kotlinAndroidExtensions)
    plugin(Deps.Plugins.cocoapods)
    plugin(Deps.Plugins.sqlDelight)
    plugin(Deps.Plugins.mokoResources)
}

group = "com.espoto"
version = "1.0.0"

repositories {
    gradlePluginPortal()
    google()
    jcenter()
    mavenCentral()
}

kotlin {
    android()
    ios()

    sourceSets {
        val commonMain by getting {
            dependencies {

                // Coroutines
                implementation(Deps.Libs.MultiPlatform.coroutines) {
                    isForce = true
                }

                // Ktor
                implementation(Deps.Libs.Ktor.client)
                implementation(Deps.Libs.Ktor.json)
                implementation(Deps.Libs.Ktor.clientLogging)
                api(Deps.Libs.Ktor.serialization)

                // Serialize
                implementation(Deps.Libs.MultiPlatform.kotlinSerialization)

                // SQL Delight
                implementation(Deps.Libs.SqlDelight.runtime)
                implementation(Deps.Libs.SqlDelight.coroutineExtensions)

                implementation(Deps.Libs.MultiPlatform.uuid)
                implementation(Deps.Libs.MultiPlatform.klock)

                api(Deps.Libs.MultiPlatform.mokoResources)
//                implementation(Deps.Libs.MultiPlatform.mokoGraphics)
//                implementation(Deps.Libs.MultiPlatform.mokoParcelize)
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }

        val androidMain by getting {
            dependencies {
                implementation(Deps.Libs.Ktor.androidClient)
                implementation(Deps.Libs.SqlDelight.androidDriver)
            }
        }
        val androidTest by getting {
            dependencies {
                implementation(kotlin("test-junit"))
                implementation("junit:junit:4.13.1")
            }
        }

        val iosMain by getting {
            dependencies {
                implementation(Deps.Libs.Ktor.iOSClient)
                implementation(Deps.Libs.SqlDelight.nativeDriver)
            }
        }
        val iosTest by getting
    }

    cocoapods {
        summary = "Shared espoto module for Android and iOS"
        homepage = "<https://espoto.tabgametest.de>"
    }
}

sqldelight {
    database("EspotoDatabase") {
        packageName = "database.generated"
    }
}

multiplatformResources {
    multiplatformResourcesPackage = "com.espoto.resources" // required
//    iosBaseLocalizationRegion = "en" // optional, default "en"
//    multiplatformResourcesSourceSet = "commonClientMain"  // optional, default "commonMain"
}

android {
    compileSdkVersion(29)

    defaultConfig {
        minSdkVersion(19)
        targetSdkVersion(29)
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    sourceSets {
        getByName("main") {
            manifest.srcFile("src/androidMain/AndroidManifest.xml")
            java.srcDirs("src/androidMain/kotlin")
            res.srcDirs("src/androidMain/res")
        }
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
        }
    }
}
Copy code
object Deps {
    object Version {
        const val kotlin = "1.4.10"

        const val gradle = "4.1.1"
        const val androidAppCompat = "1.1.0"
        const val material = "1.2.1"
        const val recyclerView = "1.1.0"
        const val swipeRefreshLayout = "1.1.0"
        const val constraintLayout = "2.0.0"
        const val lifecycle = "2.2.0"
        const val glide = "4.9.0"
        const val espressoCore = "3.2.0"
        const val testRunner = "1.2.0"
        const val testExtJunit = "1.1.1"

        const val ktorClient = "1.4.2"
        const val coroutines = "1.3.9-native-mt"
        const val kotlinxSerialization = "1.0.0-RC"
        const val kotlinxDateTime = "0.1.0"
        const val sqlDelight = "1.4.4"
        const val klock = "2.0.0-alpha"
        const val uuid = "0.2.2"
        const val prefs = "1.2.0"
        const val krypto = "1.12.0"

        const val mokoMPP = "0.8.0"
        const val mokoGraphics = "0.4.0"
        const val mokoParcelize = "0.4.0"
        const val mokoResources = "0.13.1"
        const val mokoMvvm = "0.8.0"
        const val mokoErrors = "0.3.0"
        const val mokoNetwork = "0.8.0"
        const val mokoUnits = "0.4.1"
        const val mokoPermissions = "0.6.0"
        const val mokoMedia = "0.5.0"
        const val mokoFields = "0.5.0"

        const val multiplatformSettings = "0.6.1"
    }

    object Android {
        const val compileSdk = 29
        const val targetSdk = 29
        const val minSdk = 21
    }

    object Plugins {
        val gradle = GradlePlugin(
            id = "org.jetbrains.kotlin:kotlin-gradle-plugin",
            version = Version.kotlin
        )

        val androidApplication = GradlePlugin(id = "com.android.application")
        val androidLibrary = GradlePlugin(id = "com.android.library")
        val kotlinMultiplatform = GradlePlugin(
            id = "org.jetbrains.kotlin.multiplatform",
            module = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Version.kotlin}"
        )
        val kotlinKapt = GradlePlugin(id = "kotlin-kapt")
        val kotlinAndroid = GradlePlugin(id = "kotlin-android")
        val kotlinAndroidExtensions = GradlePlugin(id = "kotlin-android-extensions")
        val kotlinSerialization = GradlePlugin(
            id = "org.jetbrains.kotlin.plugin.serialization",
            module = "org.jetbrains.kotlin:kotlin-serialization:${Version.kotlin}"
        )

        val cocoapods = GradlePlugin(id = "org.jetbrains.kotlin.native.cocoapods")
        val sqlDelight = GradlePlugin(id = "com.squareup.sqldelight")

        val mobileMultiplatform = GradlePlugin(id = "dev.icerock.mobile.multiplatform")
        val iosFramework = GradlePlugin(id = "dev.icerock.mobile.multiplatform.ios-framework")

        val mokoNetwork = GradlePlugin(
            id = "dev.icerock.mobile.multiplatform-network-generator",
            module = "dev.icerock.moko:network-generator:${Version.mokoNetwork}"
        )
        val mokoResources = GradlePlugin(
            id = "dev.icerock.mobile.multiplatform-resources",
            module = "dev.icerock.moko:resources-generator:${Version.mokoResources}"
        )
        val mokoUnits = GradlePlugin(
            id = "dev.icerock.mobile.multiplatform-units",
            module = "dev.icerock.moko:units-generator:${Version.mokoUnits}"
        )
    }

    object Libs {
        object Android {
            const val kotlinStd = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Version.kotlin}"
            const val appCompat = "androidx.appcompat:appcompat:${Version.androidAppCompat}"
            const val material = "com.google.android.material:material:${Version.material}"
            const val recyclerView = "androidx.recyclerview:recyclerview:${Version.recyclerView}"
            const val swipeRefreshLayout = "androidx.swiperefreshlayout:swiperefreshlayout:${Version.swipeRefreshLayout}"
            const val cardView = "androidx.cardview:cardview:1.0.0"
            const val constraintLayout = "androidx.constraintlayout:constraintlayout:${Version.constraintLayout}"
            const val gson = "com.google.api-client:google-api-client-gson:1.30.2"

            const val glide = "com.github.bumptech.glide:glide:${Version.glide}"
            const val exif = "androidx.exifinterface:exifinterface:1.1.0"
            const val lifecycle = "androidx.lifecycle:lifecycle-extensions:${Version.lifecycle}"
            const val ktorClientOkHttp = "io.ktor:ktor-client-okhttp:${Version.ktorClient}"
            const val volley = "com.android.volley:volley:1.1.1"
            const val jodaTime = "net.danlew:android.joda:2.10.3"
        }

        object MultiPlatform {
            const val kotlinSerialization = "org.jetbrains.kotlinx:kotlinx-serialization-core:${Version.kotlinxSerialization}"
            const val kotlinxDateTime = "org.jetbrains.kotlinx:kotlinx-datetime:${Version.kotlinxDateTime}"
            const val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Version.coroutines}"

            const val klock = "com.soywiz.korlibs.klock:klock:${Version.klock}"
            const val uuid = "com.benasher44:uuid:${Version.uuid}"
            const val prefs = "com.github.florent37:multiplatform-preferences:${Version.prefs}"
            const val krypto = "com.soywiz.korlibs.krypto:krypto:${Version.krypto}"

            val mokoResources = "dev.icerock.moko:resources:${Version.mokoResources}".mpl
            val mokoParcelize = "dev.icerock.moko:parcelize:${Version.mokoParcelize}".mpl
            val mokoGraphics = "dev.icerock.moko:graphics:${Version.mokoGraphics}".mpl
            val mokoMvvm = "dev.icerock.moko:mvvm:${Version.mokoMvvm}".mpl
            val mokoErrors = "dev.icerock.moko:errors:${Version.mokoErrors}".mpl
            val mokoNetwork = "dev.icerock.moko:network:${Version.mokoNetwork}".mpl
            val mokoNetworkErrors = "dev.icerock.moko:network-errors:${Version.mokoNetwork}".mpl
            val mokoPermissions = "dev.icerock.moko:permissions:${Version.mokoPermissions}".mpl
            val mokoMedia = "dev.icerock.moko:media:${Version.mokoMedia}".mpl
            val mokoUnits = "dev.icerock.moko:units:${Version.mokoUnits}".mpl
            val mokoFields = "dev.icerock.moko:fields:${Version.mokoFields}".mpl
            val multiplatformSettings = "com.russhwolf:multiplatform-settings:${Version.multiplatformSettings}".mpl
        }

        object Ktor {
            const val client = "io.ktor:ktor-client-core:${Version.ktorClient}"
            const val clientLogging = "io.ktor:ktor-client-logging:${Version.ktorClient}"
            const val androidClient = "io.ktor:ktor-client-android:${Version.ktorClient}"
            const val iOSClient = "io.ktor:ktor-client-ios:${Version.ktorClient}"
            const val serialization = "io.ktor:ktor-client-serialization:${Deps.Version.ktorClient}"
            const val json = "io.ktor:ktor-client-json:${Deps.Version.ktorClient}"
        }

        object SqlDelight {
            const val runtime = "com.squareup.sqldelight:runtime:${Version.sqlDelight}"
            const val coroutineExtensions = "com.squareup.sqldelight:coroutines-extensions:${Version.sqlDelight}"

            const val androidDriver = "com.squareup.sqldelight:android-driver:${Version.sqlDelight}"
            const val nativeDriver = "com.squareup.sqldelight:native-driver:${Version.sqlDelight}"
            const val nativeDriverMacos = "com.squareup.sqldelight:native-driver-macosx64:${Version.sqlDelight}"
        }
    }

    object Modules {
        val domain = MultiPlatformModule(
            name = ":mpp-library:domain",
            exported = true
        )

        object Feature {
            val config = MultiPlatformModule(
                name = ":mpp-library:feature:config",
                exported = true
            )
            val list = MultiPlatformModule(
                name = ":mpp-library:feature:list",
                exported = true
            )
        }
    }

    private val String.mpl: MultiPlatformLibrary
        get() = MultiPlatformLibrary(
            common = this,
            iosX64 = this.replace(Regex("(.*):(.*):(.*)"), "$1:$2-iosx64:$3"),
            iosArm64 = this.replace(Regex("(.*):(.*):(.*)"), "$1:$2-iosarm64:$3")
        )
}
a

alex009

12/03/2020, 2:38 AM
hello! strange error, because you have configure required value... please run gradle build with
--stacktrace
flag.
./gradlew assemble --stacktrace
for example
j

Julius

12/03/2020, 8:47 AM
* What went wrong: Cannot convert the provided notation to an object of type Dependency: MultiPlatformLibrary(android=null, common=dev.icerock.mokoresources0.13.1, iosX64=dev.icerock.mokoresources iosx640.13.1, iosArm64=dev.icerock.mokoresources iosarm640.13.1). The following types/formats are supported: - Instances of Dependency. - String or CharSequence values, for example 'org.gradlegradle core1.0'. - Maps, for example [group: 'org.gradle', name: 'gradle-core', version: '1.0']. - FileCollections, for example files('some.jar', 'someOther.jar'). - Projects, for example project('someproject:path'). - ClassPathNotation, for example gradleApi(). * Exception is: org.gradle.internal.typeconversion.UnsupportedNotationException: Cannot convert the provided notation to an object of type Dependency: MultiPlatformLibrary(android=null, common=dev.icerock.mokoresources0.13.1, iosX64=dev.icerock.mokoresources iosx640.13.1, iosArm64=dev.icerock.mokoresources iosarm640.13.1). The following types/formats are supported: - Instances of Dependency. - String or CharSequence values, for example 'org.gradlegradle core1.0'. - Maps, for example [group: 'org.gradle', name: 'gradle-core', version: '1.0']. - FileCollections, for example files('some.jar', 'someOther.jar'). - Projects, for example project('someproject:path'). - ClassPathNotation, for example gradleApi().
@alex009 I have uploaded a sample project to github: https://github.com/frodob/MokoResourcesTest
a

alex009

12/03/2020, 10:54 AM
j

Julius

12/03/2020, 11:02 AM
Awesome! Thank you very much!
@alex009 Almost there, but I think I'm still missing something. The auto-generated MR file is missing the actual implementation for iOS: Expected object 'MR' has no actual declaration in module MokoResourcesTest.SharedCode.iosArm64Main for Native Expected object 'MR' has no actual declaration in module MokoResourcesTest.SharedCode.iosX64Main for Native
a

alex009

12/03/2020, 4:23 PM
code generates when you compile specific target. if you want to generate actual manually - run
generateMRiosX64Main
gradle task
448 Views