icerockdev / moko-resources

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

Help in retrieving the string value from key #332

Open Takashi-san opened 2 years ago

Takashi-san commented 2 years ago

Hi, I've been trying to use the string resource on the iOS side but I'm always getting back the string key instead of its value. Ways that I have tried to access the resource:

// key = my_key, value = "my text"

let resource = MR.strings().my_key
// log: dev.icerock.moko.resources.StringResource@1ca6668

NSLocalizedString(resource.resourceid, bundle: resource.bundle, comment: "")
// return: "my_key"

MokoUtils.companion.getStringDesc(resource: resource).localized()
// return: "my_key"

MokoUtils.companion.getString()
// return: "ResourceStringDesc(stringRes=dev.icerock.moko.resources.StringResource@1ca6668)"

The MokoUtils on android side:

class MokoUtils {
    companion object {
        fun getStringDesc(resource: StringResource) : StringDesc {
            return StringDesc.Resource(resource)
        }

        fun getString() : String {
            return StringDesc.Resource(MR.strings.my_key).toString()
        }
    }
}

I believe that it was unable to find my bundle according to what I saw in other issues and the log of resource.bundle. I tried to load the bundle but it never loaded.

resource.bundle
// log: </Users/myUser/Library/Developer/CoreSimulator/Devices/B91029C6-D738-452A-8646-CAECFE8798C8/data/Containers/Bundle/Application/515C8A5B-EBBF-440D-BD49-C8A4A41A1A9F/MyApp.app/android:shared_core.bundle> (not yet loaded)

Maybe some configuration of my project isn't right, but I can't figure out what is it that is wrong. Android project build.gradle:

buildscript {
    ext.kotlin_version = '1.5.31'
    ext.dokka_version = '0.9.16'
    ext.ktor_version = '1.4.3'
    ext.lifecycle_version = '2.3.0'
    ext.okhttp_version = '4.9.0'
    ext.appcompat_version = '1.2.0'
    ext.corektx_version = '1.5.0'
    ext.navigation_version = '2.3.4'
    ext.paging_version = '2.1.2'
    ext.eventbus_version = '3.2.0'
    ext.room_version = '2.4.0-alpha03'
    ext.workmanager_version = '2.5.0'
    ext.startup_version = '1.0.0'
    ext.glide_version = '4.11.0'
    ext.constraintlayout_version = '2.0.4'
    ext.material_version = '1.3.0'
    ext.cardview_version = '1.0.0'
    ext.flexbox_version = '2.0.1'
    ext.circleimageview_version = '3.1.0'
    ext.coroutine_version = '1.5.2'

    if (project.compileAsLibrary == "true") {
        ext.tripletPlayVersion = "2.6.1"
    } else {
        ext.tripletPlayVersion = "3.6.0"
    }

    ext.hbVersionName = "1.20.111"

    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
        gradlePluginPortal()
        jcenter()

    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.4'
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}")
        classpath("org.jetbrains.kotlin:kotlin-serialization:${kotlin_version}")
        classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}"
        classpath 'com.google.gms:google-services:4.3.10'
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
        classpath 'com.google.firebase:perf-plugin:1.4.1'  // Performance Monitoring plugin
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:${navigation_version}"
        classpath "com.vanniktech:gradle-android-junit-jacoco-plugin:0.16.0"
        classpath "com.github.kezong:fat-aar:1.3.6"
        classpath "dev.icerock.moko:resources-generator:0.17.4"
        classpath "org.jlleitschuh.gradle:ktlint-gradle:9.2.1"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url "https://jitpack.io" }
        maven { url 'https://maven.fabric.io/public' }
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

apply plugin: 'org.jlleitschuh.gradle.ktlint'

shared_core module build.gradle:

import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget

plugins {
    kotlin("multiplatform")
    kotlin("native.cocoapods")
    id("com.android.library")
    id("dev.icerock.mobile.multiplatform-resources")
    id("kotlin-parcelize")
    id("org.jlleitschuh.gradle.ktlint")
    kotlin("plugin.serialization")
    id("com.chromaticnoise.multiplatform-swiftpackage") version "2.0.3"
}

version = "1.0"

kotlin {
    android()

    val iosTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget = when {
        System.getenv("SDK_NAME")?.startsWith("iphoneos") == true -> ::iosArm64
        else -> ::iosX64
    }

    iosTarget("ios") {}

    cocoapods {
        summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        ios.deploymentTarget = "11"
        frameworkName = "shared_core"
        xcodeConfigurationToNativeBuildType["Beta"] = org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType.RELEASE
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2")
                api("org.jetbrains.kotlinx:kotlinx-datetime:0.3.1")

                implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1")
                implementation("co.touchlab:stately-isolate:1.1.4-a1")
                implementation("co.touchlab:stately-iso-collections:1.1.4-a1")

                api("dev.icerock.moko:resources:0.17.4")
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }
        val androidMain by getting {
            dependencies {
                implementation("androidx.appcompat:appcompat:1.2.0")
                implementation("com.google.android.material:material:1.3.0")
            }
        }
        val androidTest by getting {
            dependencies {
                implementation(kotlin("test-junit"))
            }
        }
        val iosMain by getting {
            dependencies {
            }
        }
        val iosTest by getting
    }
}

multiplatformResources {
    multiplatformResourcesPackage = "com.app.id"
    iosBaseLocalizationRegion = "pt"
    multiplatformResourcesSourceSet = "commonMain"
}

multiplatformSwiftPackage {
    packageName("SharedCorePackage")
    swiftToolsVersion("5.3")
    targetPlatforms {
        iOS { v("13") }
    }
}

android {
    compileSdkVersion(31)
    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    defaultConfig {
        minSdkVersion(22)
        targetSdkVersion(31)
    }
}

Localization values added to the info.plist of iOS app project and target:

<key>CFBundleLocalizations</key>
    <array>
        <string>pt</string>
        <string>en</string>
        <string>es</string>
    </array>

Build script phase added to the end of the build phases:

"$SRCROOT/../android/gradlew" -p "$SRCROOT/../android/" :shared_core:copyFrameworkResourcesToApp \
    -Pmoko.resources.PLATFORM_NAME=$PLATFORM_NAME \
    -Pmoko.resources.CONFIGURATION=$CONFIGURATION \
    -Pmoko.resources.BUILT_PRODUCTS_DIR=$BUILT_PRODUCTS_DIR \
    -Pmoko.resources.CONTENTS_FOLDER_PATH=$CONTENTS_FOLDER_PATH\
    -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \
    -Pkotlin.native.cocoapods.archs="$ARCHS" \
    -Pkotlin.native.cocoapods.configuration=$CONFIGURATION 

Any help now is greatly appreciated.

Alex009 commented 2 years ago

seems that all configured ok. can you show contents of compiled framework and app? run ls -lR . inside compiled app and compiled framework

Takashi-san commented 2 years ago

The result from path android/shared_core/build/cocoapods/framework :

total 0
drwxr-xr-x  7 myUser  staff  224 18 Abr 12:25 shared_core.framework

./shared_core.framework:
total 120968
drwxr-xr-x  3 myUser  staff        96 18 Abr 12:25 Headers
-rw-r--r--  1 myUser  staff       949 18 Abr 12:26 Info.plist
drwxr-xr-x  3 myUser  staff        96 18 Abr 11:28 Modules
drwxr-xr-x  3 myUser  staff        96 18 Abr 12:25 android:shared_core.bundle
-rw-r--r--  1 myUser  staff  61312288 18 Abr 12:26 shared_core

./shared_core.framework/Headers:
total 4224
-rw-r--r--  1 myUser  staff  1644008 18 Abr 12:26 shared_core.h

./shared_core.framework/Modules:
total 8
-rw-r--r--  1 myUser  staff  108 18 Abr 12:26 module.modulemap

./shared_core.framework/android:shared_core.bundle:
total 0
drwxr-xr-x  4 myUser  staff  128 18 Abr 12:25 Contents

./shared_core.framework/android:shared_core.bundle/Contents:
total 8
-rw-r--r--  1 myUser  staff  507 18 Abr 12:26 Info.plist
drwxr-xr-x  8 myUser  staff  256 18 Abr 12:25 Resources

./shared_core.framework/android:shared_core.bundle/Contents/Resources:
total 1296
-rw-r--r--  1 myUser  staff  660184 18 Abr 12:26 Assets.car
drwxr-xr-x  3 myUser  staff      96 18 Abr 12:25 Base.lproj
drwxr-xr-x  3 myUser  staff      96 18 Abr 12:25 en.lproj
drwxr-xr-x  3 myUser  staff      96 18 Abr 12:25 es.lproj
drwxr-xr-x  2 myUser  staff      64 18 Abr 12:25 files
drwxr-xr-x  3 myUser  staff      96 18 Abr 12:25 pt.lproj

./shared_core.framework/android:shared_core.bundle/Contents/Resources/Base.lproj:
total 400
-rw-r--r--  1 myUser  staff  203562 18 Abr 12:26 Localizable.strings

./shared_core.framework/android:shared_core.bundle/Contents/Resources/en.lproj:
total 360
-rw-r--r--  1 myUser  staff  181955 18 Abr 12:26 Localizable.strings

./shared_core.framework/android:shared_core.bundle/Contents/Resources/es.lproj:
total 392
-rw-r--r--  1 myUser  staff  199358 18 Abr 12:26 Localizable.strings

./shared_core.framework/android:shared_core.bundle/Contents/Resources/files:
total 0

./shared_core.framework/android:shared_core.bundle/Contents/Resources/pt.lproj:
total 400
-rw-r--r--  1 myUser  staff  203562 18 Abr 12:26 Localizable.strings

What are you looking for in the compiled app path? If I try to run this on the android/app/build folder the log is too big and I can't share it.

Alex009 commented 2 years ago

in compiled app i see that bundle with resources exist and should correctly read. please try to configure reproducer from sample of moko-resources

JagadishaIncture commented 8 months ago

Facing same issue