icerockdev / moko-resources

Resources access for mobile (android & ios) Kotlin Multiplatform development
https://moko.icerock.dev/
Apache License 2.0
1.09k stars 120 forks source link

IOS crash, kotlin.IllegalArgumentException: can't read UIImage of ..., 0.24.0-beta-1 #680

Closed parfenovedyard closed 5 months ago

parfenovedyard commented 5 months ago

There is a module "resources" with moko-resources in project.

If I try to load image on IOS emulator I had a crash:

kotlin.IllegalArgumentException: can't read UIImage of ImageResource(assetImageName=pic_plug, bundle=NSBundle </Users/username/Library/Developer/CoreSimulator/Devices/7BD82449-BAA7-463F-8A97-D967D0A2C8D8/data/Containers/Bundle/Application/742CD347-DE49-4030-AE6D-1B4FAE53411A/ExampleApp.app/ExampleApp:resources.bundle> (not yet loaded))

But on android svg and png files loaded well, and fonts and strings also loaded well on Android and Ios.

My module setup:

toml file: [versions] jvm = "11" agp = "8.2.0" kotlin = "1.9.23" compose-plugin = "1.6.2" moko-resources = "0.24.0-beta-1" [libraries] moko-resources = { module = "dev.icerock.moko:resources", version.ref = "moko-resources" } moko-resources-compose = { module = "dev.icerock.moko:resources-compose", version.ref = "moko-resources" } [plugins] androidLibrary = { id = "com.android.library", version.ref = "agp" } jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" } kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } mokoResources = { id = "dev.icerock.mobile.multiplatform-resources", version.ref = "moko-resources" } [bundles] moko-resources = [ "moko-resources", "moko-resources-compose" ]

module build.gradle file: plugins { alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.androidLibrary) alias(libs.plugins.mokoResources) alias(libs.plugins.jetbrainsCompose) }

kotlin { androidTarget { compilations.all { kotlinOptions { jvmTarget = libs.versions.jvm.get() } } }

listOf(
    iosX64(),
    iosArm64(),
    iosSimulatorArm64()
).forEach {
    it.binaries.framework {
        baseName = "resources"
        isStatic = true
    }
}

sourceSets {
    commonMain.dependencies {
        implementation(libs.bundles.moko.resources)

        implementation(compose.ui)
        implementation(compose.runtime)
        implementation(compose.material3)
        implementation(compose.animation)
        implementation(compose.foundation)
    }
}

multiplatformResources {
    resourcesPackage.set("com.pe.exampleApp.resources")
}

}

android { namespace = "com.pe.exampleApp.resources" compileSdk = libs.versions.android.compileSdk.get().toInt() compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } defaultConfig { minSdk = libs.versions.android.minSdk.get().toInt() } }

and also added script to Build phase in Xcode:

"$SRCROOT/../gradlew" -p "$SRCROOT/../" :resources:copyFrameworkResourcesToApp \ -Pmoko.resources.PLATFORM_NAME="$PLATFORM_NAME" \ -Pmoko.resources.CONFIGURATION="$CONFIGURATION" \ -Pmoko.resources.ARCHS="$ARCHS" \ -Pmoko.resources.BUILT_PRODUCTS_DIR="$BUILT_PRODUCTS_DIR" \ -Pmoko.resources.CONTENTS_FOLDER_PATH="$CONTENTS_FOLDER_PATH"

In generated MR object I see all necessary images.

Looks like it happens if toUIImage() fun in actual class ImageResource in Ios part returns null and than actual fun painterResource thrown an Exception

ExNDY commented 5 months ago

Hi, can u send sample or branch with problems?

parfenovedyard commented 5 months ago

Hi, can u send sample or branch with problems?

https://github.com/parfenovedyard/MokoResSample

While preparing sample noticed that only dark theme causes crash. On light theme everything works fine, android works fine on dark and light theme.

Alex009 commented 5 months ago

@parfenovedyard you should apply moko-resources plugin to https://github.com/parfenovedyard/MokoResSample/blob/a46e516150a015a47066186fcce63dd3ec476c01/composeApp/build.gradle.kts#L6

and should not create framework here https://github.com/parfenovedyard/MokoResSample/blob/a46e516150a015a47066186fcce63dd3ec476c01/resources/build.gradle.kts#L22

and also you should change order of build phases in xcode - at first you should compile kotlin framework, then you should copy resources from framework by :composeApp:copyFrameworkResourcesToApp

your current config very not optimal (long build time required), but it's not cause of issue. we will research why dark theme image broken

ExNDY commented 5 months ago

crash on ios with dark images, will be fixed in 0.24.0-beta-2 fix contains in #674

parfenovedyard commented 5 months ago

@parfenovedyard you should apply moko-resources plugin to https://github.com/parfenovedyard/MokoResSample/blob/a46e516150a015a47066186fcce63dd3ec476c01/composeApp/build.gradle.kts#L6

and should not create framework here https://github.com/parfenovedyard/MokoResSample/blob/a46e516150a015a47066186fcce63dd3ec476c01/resources/build.gradle.kts#L22

and also you should change order of build phases in xcode - at first you should compile kotlin framework, then you should copy resources from framework by :composeApp:copyFrameworkResourcesToApp

your current config very not optimal (long build time required), but it's not cause of issue. we will research why dark theme image broken

got it, thanks.

Regarding framework, if i change code like this:

image

without creating framework, just targets. I got ios build error:

image

May add to readme comment about order of build phases in xcode, cz in readme we need add to the end.

image
Alex009 commented 5 months ago

i already said that you should use :composeApp:copyFrameworkResourcesToApp but you still use :resources:copyFrameworkResourcesToApp :)

you should use project that produce ios framework. it's composeApp in your case

Alex009 commented 5 months ago

@ExNDY please add in readme that build phase should be after kotlin framework compilation

May add to readme comment about order of build phases in xcode, cz in readme we need add to the end.