diff --git a/android/src/main/java/co/nimblehq/kmm/template/ui/screens/home/HomeScreen.kt b/android/src/main/java/co/nimblehq/kmm/template/ui/screens/home/HomeScreen.kt
index 800e2bc7..4b53d538 100644
--- a/android/src/main/java/co/nimblehq/kmm/template/ui/screens/home/HomeScreen.kt
+++ b/android/src/main/java/co/nimblehq/kmm/template/ui/screens/home/HomeScreen.kt
@@ -4,8 +4,11 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
-import co.nimblehq.kmm.template.Greeting
+import co.nimblehq.kmm.template.Strings
+import co.nimblehq.kmm.template.getPlatform
+import co.nimblehq.kmm.template.sharedres.SharedRes
import co.nimblehq.kmm.template.ui.theme.ComposeTheme
@Composable
@@ -14,7 +17,12 @@ fun HomeScreen() {
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
- Text(text = Greeting().greet())
+ Text(
+ text = Strings(LocalContext.current).get(
+ id = SharedRes.strings.greeting,
+ args = listOf(getPlatform().name)
+ )
+ )
}
}
diff --git a/build.gradle.kts b/build.gradle.kts
index 09329006..7fa6d01a 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -11,6 +11,12 @@ plugins {
kotlin(Plugins.KOTLIN_SERIALIZATION) version Versions.KOTLIN
}
+buildscript {
+ dependencies {
+ classpath(Dependencies.Moko.RESOURCES_GENERATOR)
+ }
+}
+
detekt {
toolVersion = Versions.DETEKT
config.setFrom("detekt.yml")
diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt
index f7ae174a..b2c9fae8 100644
--- a/buildSrc/src/main/java/Dependencies.kt
+++ b/buildSrc/src/main/java/Dependencies.kt
@@ -45,6 +45,13 @@ object Dependencies {
const val TIMBER = "com.jakewharton.timber:timber:${Versions.TIMBER}"
}
+ object Moko {
+ const val RESOURCES_GENERATOR = "dev.icerock.moko:resources-generator:${Versions.MOKO_RESOURCES}"
+ const val RESOURCES = "dev.icerock.moko:resources:${Versions.MOKO_RESOURCES}"
+ const val RESOURCES_COMPOSE = "dev.icerock.moko:resources-compose:${Versions.MOKO_RESOURCES}"
+ const val GRAPHICS = "dev.icerock.moko:graphics:${Versions.MOKO_GRAPHICS}"
+ }
+
object Test {
const val COMPOSE_UI_TEST_JUNIT = "androidx.compose.ui:ui-test-junit4:${Versions.COMPOSE}"
const val COMPOSE_UI_TEST_MANIFEST = "androidx.compose.ui:ui-test-manifest:${Versions.COMPOSE}"
@@ -60,6 +67,8 @@ object Dependencies {
const val MOCKK = "io.mockk:mockk:${Versions.MOCKK}"
const val MOCKK_ANDROID = "io.mockk:mockk-android:${Versions.MOCKK}"
+ const val MOKO_RESOURCES_TEST = "dev.icerock.moko:resources-test:${Versions.MOKO_RESOURCES}"
+
const val ROBOLECTRIC = "org.robolectric:robolectric:${Versions.ROBOLECTRIC}"
const val TURBINE = "app.cash.turbine:turbine:${Versions.TURBINE}"
diff --git a/buildSrc/src/main/java/Plugins.kt b/buildSrc/src/main/java/Plugins.kt
index 671a93ab..ab2a1e6c 100644
--- a/buildSrc/src/main/java/Plugins.kt
+++ b/buildSrc/src/main/java/Plugins.kt
@@ -14,5 +14,7 @@ object Plugins {
const val KOVER = "org.jetbrains.kotlinx.kover"
const val KSP = "com.google.devtools.ksp"
+ const val MOKO = "dev.icerock.mobile.multiplatform-resources"
+
const val MULTIPLATFORM = "multiplatform"
}
diff --git a/buildSrc/src/main/java/Versions.kt b/buildSrc/src/main/java/Versions.kt
index 2bfae497..ba0f3739 100644
--- a/buildSrc/src/main/java/Versions.kt
+++ b/buildSrc/src/main/java/Versions.kt
@@ -33,6 +33,9 @@ object Versions {
const val MOCKATIVE = "1.3.0"
const val MOCKK = "1.13.3"
+ const val MOKO_RESOURCES = "0.23.0"
+ const val MOKO_GRAPHICS = "0.9.0"
+
const val NAPIER = "2.6.1"
const val ROBOLECTRIC = "4.9.1"
diff --git a/sample/android/src/main/java/co/nimblehq/kmm/template/ui/screens/home/HomeScreen.kt b/sample/android/src/main/java/co/nimblehq/kmm/template/ui/screens/home/HomeScreen.kt
index 800e2bc7..4b53d538 100644
--- a/sample/android/src/main/java/co/nimblehq/kmm/template/ui/screens/home/HomeScreen.kt
+++ b/sample/android/src/main/java/co/nimblehq/kmm/template/ui/screens/home/HomeScreen.kt
@@ -4,8 +4,11 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
-import co.nimblehq.kmm.template.Greeting
+import co.nimblehq.kmm.template.Strings
+import co.nimblehq.kmm.template.getPlatform
+import co.nimblehq.kmm.template.sharedres.SharedRes
import co.nimblehq.kmm.template.ui.theme.ComposeTheme
@Composable
@@ -14,7 +17,12 @@ fun HomeScreen() {
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
- Text(text = Greeting().greet())
+ Text(
+ text = Strings(LocalContext.current).get(
+ id = SharedRes.strings.greeting,
+ args = listOf(getPlatform().name)
+ )
+ )
}
}
diff --git a/sample/build.gradle.kts b/sample/build.gradle.kts
index 09329006..7fa6d01a 100644
--- a/sample/build.gradle.kts
+++ b/sample/build.gradle.kts
@@ -11,6 +11,12 @@ plugins {
kotlin(Plugins.KOTLIN_SERIALIZATION) version Versions.KOTLIN
}
+buildscript {
+ dependencies {
+ classpath(Dependencies.Moko.RESOURCES_GENERATOR)
+ }
+}
+
detekt {
toolVersion = Versions.DETEKT
config.setFrom("detekt.yml")
diff --git a/sample/buildSrc/src/main/java/Dependencies.kt b/sample/buildSrc/src/main/java/Dependencies.kt
index f7ae174a..b2c9fae8 100644
--- a/sample/buildSrc/src/main/java/Dependencies.kt
+++ b/sample/buildSrc/src/main/java/Dependencies.kt
@@ -45,6 +45,13 @@ object Dependencies {
const val TIMBER = "com.jakewharton.timber:timber:${Versions.TIMBER}"
}
+ object Moko {
+ const val RESOURCES_GENERATOR = "dev.icerock.moko:resources-generator:${Versions.MOKO_RESOURCES}"
+ const val RESOURCES = "dev.icerock.moko:resources:${Versions.MOKO_RESOURCES}"
+ const val RESOURCES_COMPOSE = "dev.icerock.moko:resources-compose:${Versions.MOKO_RESOURCES}"
+ const val GRAPHICS = "dev.icerock.moko:graphics:${Versions.MOKO_GRAPHICS}"
+ }
+
object Test {
const val COMPOSE_UI_TEST_JUNIT = "androidx.compose.ui:ui-test-junit4:${Versions.COMPOSE}"
const val COMPOSE_UI_TEST_MANIFEST = "androidx.compose.ui:ui-test-manifest:${Versions.COMPOSE}"
@@ -60,6 +67,8 @@ object Dependencies {
const val MOCKK = "io.mockk:mockk:${Versions.MOCKK}"
const val MOCKK_ANDROID = "io.mockk:mockk-android:${Versions.MOCKK}"
+ const val MOKO_RESOURCES_TEST = "dev.icerock.moko:resources-test:${Versions.MOKO_RESOURCES}"
+
const val ROBOLECTRIC = "org.robolectric:robolectric:${Versions.ROBOLECTRIC}"
const val TURBINE = "app.cash.turbine:turbine:${Versions.TURBINE}"
diff --git a/sample/buildSrc/src/main/java/Plugins.kt b/sample/buildSrc/src/main/java/Plugins.kt
index 671a93ab..ab2a1e6c 100644
--- a/sample/buildSrc/src/main/java/Plugins.kt
+++ b/sample/buildSrc/src/main/java/Plugins.kt
@@ -14,5 +14,7 @@ object Plugins {
const val KOVER = "org.jetbrains.kotlinx.kover"
const val KSP = "com.google.devtools.ksp"
+ const val MOKO = "dev.icerock.mobile.multiplatform-resources"
+
const val MULTIPLATFORM = "multiplatform"
}
diff --git a/sample/buildSrc/src/main/java/Versions.kt b/sample/buildSrc/src/main/java/Versions.kt
index 2bfae497..ba0f3739 100644
--- a/sample/buildSrc/src/main/java/Versions.kt
+++ b/sample/buildSrc/src/main/java/Versions.kt
@@ -33,6 +33,9 @@ object Versions {
const val MOCKATIVE = "1.3.0"
const val MOCKK = "1.13.3"
+ const val MOKO_RESOURCES = "0.23.0"
+ const val MOKO_GRAPHICS = "0.9.0"
+
const val NAPIER = "2.6.1"
const val ROBOLECTRIC = "4.9.1"
diff --git a/sample/ios/sample/Configurations/Plists/Info.plist b/sample/ios/sample/Configurations/Plists/Info.plist
index b18749da..79ad0959 100644
--- a/sample/ios/sample/Configurations/Plists/Info.plist
+++ b/sample/ios/sample/Configurations/Plists/Info.plist
@@ -24,8 +24,12 @@
armv7
- UILaunchStoryboardName
- LaunchScreen
+ CFBundleLocalizations
+
+ en
+
+ UILaunchStoryboardName
+ LaunchScreen
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
diff --git a/sample/shared/build.gradle.kts b/sample/shared/build.gradle.kts
index b9cca8ba..c2d6dae4 100644
--- a/sample/shared/build.gradle.kts
+++ b/sample/shared/build.gradle.kts
@@ -11,6 +11,7 @@ plugins {
id(Plugins.KOVER)
id(Plugins.KSP)
id(Plugins.BUILD_KONFIG)
+ id(Plugins.MOKO)
}
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
@@ -36,6 +37,8 @@ kotlin {
podfile = project.file("../ios/Podfile")
framework {
baseName = "shared"
+ export(Dependencies.Moko.RESOURCES)
+ export(Dependencies.Moko.GRAPHICS)
}
xcodeConfigurationToNativeBuildType["Debug Staging"] = NativeBuildType.DEBUG
@@ -59,6 +62,11 @@ kotlin {
implementation(AUTH)
}
+ with(Dependencies.Moko) {
+ api(RESOURCES)
+ // api(RESOURCES_COMPOSE) FIXME: Cannot build the shared module with this dependency
+ }
+
implementation(Dependencies.Log.NAPIER)
}
}
@@ -71,6 +79,7 @@ kotlin {
implementation(KOTLINX_RESOURCES)
implementation(MOCKATIVE)
implementation(TURBINE)
+ implementation(MOKO_RESOURCES_TEST)
}
}
}
@@ -145,3 +154,8 @@ buildkonfig {
)
}
}
+
+multiplatformResources {
+ multiplatformResourcesPackage = "co.nimblehq.kmm.template.sharedres"
+ multiplatformResourcesClassName = "SharedRes"
+}
diff --git a/sample/shared/src/androidMain/kotlin/co/nimblehq/kmm/template/Strings.kt b/sample/shared/src/androidMain/kotlin/co/nimblehq/kmm/template/Strings.kt
new file mode 100644
index 00000000..12095024
--- /dev/null
+++ b/sample/shared/src/androidMain/kotlin/co/nimblehq/kmm/template/Strings.kt
@@ -0,0 +1,20 @@
+package co.nimblehq.kmm.template
+
+import android.content.Context
+import dev.icerock.moko.resources.StringResource
+import dev.icerock.moko.resources.desc.Resource
+import dev.icerock.moko.resources.desc.StringDesc
+import dev.icerock.moko.resources.format
+
+actual class Strings(private val context: Context) {
+ actual fun get(
+ id: StringResource,
+ args: List,
+ ): String {
+ return if (args.isEmpty()) {
+ StringDesc.Resource(id).toString(context = context)
+ } else {
+ id.format(*args.toTypedArray()).toString(context)
+ }
+ }
+}
diff --git a/sample/shared/src/commonMain/kotlin/co/nimblehq/kmm/template/Strings.kt b/sample/shared/src/commonMain/kotlin/co/nimblehq/kmm/template/Strings.kt
new file mode 100644
index 00000000..2348968a
--- /dev/null
+++ b/sample/shared/src/commonMain/kotlin/co/nimblehq/kmm/template/Strings.kt
@@ -0,0 +1,7 @@
+package co.nimblehq.kmm.template
+
+import dev.icerock.moko.resources.StringResource
+
+expect class Strings {
+ fun get(id: StringResource, args: List = emptyList()): String
+}
diff --git a/sample/shared/src/commonMain/resources/MR/base/strings.xml b/sample/shared/src/commonMain/resources/MR/base/strings.xml
new file mode 100644
index 00000000..7b75c648
--- /dev/null
+++ b/sample/shared/src/commonMain/resources/MR/base/strings.xml
@@ -0,0 +1,3 @@
+
+ Hello, %s!
+
diff --git a/sample/shared/src/iosMain/kotlin/co/nimblehq/kmm/template/Strings.kt b/sample/shared/src/iosMain/kotlin/co/nimblehq/kmm/template/Strings.kt
new file mode 100644
index 00000000..4c9d3a8d
--- /dev/null
+++ b/sample/shared/src/iosMain/kotlin/co/nimblehq/kmm/template/Strings.kt
@@ -0,0 +1,19 @@
+package co.nimblehq.kmm.template
+
+import dev.icerock.moko.resources.StringResource
+import dev.icerock.moko.resources.desc.Resource
+import dev.icerock.moko.resources.desc.StringDesc
+import dev.icerock.moko.resources.format
+
+actual class Strings {
+ actual fun get(
+ id: StringResource,
+ args: List,
+ ): String {
+ return if (args.isEmpty()) {
+ StringDesc.Resource(id).localized()
+ } else {
+ id.format(*args.toTypedArray()).localized()
+ }
+ }
+}
diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts
index b9cca8ba..c2d6dae4 100644
--- a/shared/build.gradle.kts
+++ b/shared/build.gradle.kts
@@ -11,6 +11,7 @@ plugins {
id(Plugins.KOVER)
id(Plugins.KSP)
id(Plugins.BUILD_KONFIG)
+ id(Plugins.MOKO)
}
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
@@ -36,6 +37,8 @@ kotlin {
podfile = project.file("../ios/Podfile")
framework {
baseName = "shared"
+ export(Dependencies.Moko.RESOURCES)
+ export(Dependencies.Moko.GRAPHICS)
}
xcodeConfigurationToNativeBuildType["Debug Staging"] = NativeBuildType.DEBUG
@@ -59,6 +62,11 @@ kotlin {
implementation(AUTH)
}
+ with(Dependencies.Moko) {
+ api(RESOURCES)
+ // api(RESOURCES_COMPOSE) FIXME: Cannot build the shared module with this dependency
+ }
+
implementation(Dependencies.Log.NAPIER)
}
}
@@ -71,6 +79,7 @@ kotlin {
implementation(KOTLINX_RESOURCES)
implementation(MOCKATIVE)
implementation(TURBINE)
+ implementation(MOKO_RESOURCES_TEST)
}
}
}
@@ -145,3 +154,8 @@ buildkonfig {
)
}
}
+
+multiplatformResources {
+ multiplatformResourcesPackage = "co.nimblehq.kmm.template.sharedres"
+ multiplatformResourcesClassName = "SharedRes"
+}
diff --git a/shared/src/androidMain/kotlin/co/nimblehq/kmm/template/Strings.kt b/shared/src/androidMain/kotlin/co/nimblehq/kmm/template/Strings.kt
new file mode 100644
index 00000000..12095024
--- /dev/null
+++ b/shared/src/androidMain/kotlin/co/nimblehq/kmm/template/Strings.kt
@@ -0,0 +1,20 @@
+package co.nimblehq.kmm.template
+
+import android.content.Context
+import dev.icerock.moko.resources.StringResource
+import dev.icerock.moko.resources.desc.Resource
+import dev.icerock.moko.resources.desc.StringDesc
+import dev.icerock.moko.resources.format
+
+actual class Strings(private val context: Context) {
+ actual fun get(
+ id: StringResource,
+ args: List,
+ ): String {
+ return if (args.isEmpty()) {
+ StringDesc.Resource(id).toString(context = context)
+ } else {
+ id.format(*args.toTypedArray()).toString(context)
+ }
+ }
+}
diff --git a/shared/src/androidUnitTest/kotlin/co/nimblehq/kmm/template/androidTest.kt b/shared/src/androidUnitTest/kotlin/co/nimblehq/kmm/template/androidTest.kt
deleted file mode 100644
index 900b0bb6..00000000
--- a/shared/src/androidUnitTest/kotlin/co/nimblehq/kmm/template/androidTest.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package co.nimblehq.kmm.template
-
-import org.junit.Assert.assertTrue
-import org.junit.Test
-
-class AndroidGreetingTest {
-
- @Test
- fun testExample() {
- assertTrue("Check Android is mentioned", Greeting().greet().contains("Android"))
- }
-}
diff --git a/shared/src/commonMain/kotlin/co/nimblehq/kmm/template/Strings.kt b/shared/src/commonMain/kotlin/co/nimblehq/kmm/template/Strings.kt
new file mode 100644
index 00000000..2348968a
--- /dev/null
+++ b/shared/src/commonMain/kotlin/co/nimblehq/kmm/template/Strings.kt
@@ -0,0 +1,7 @@
+package co.nimblehq.kmm.template
+
+import dev.icerock.moko.resources.StringResource
+
+expect class Strings {
+ fun get(id: StringResource, args: List = emptyList()): String
+}
diff --git a/shared/src/commonMain/resources/MR/base/strings.xml b/shared/src/commonMain/resources/MR/base/strings.xml
new file mode 100644
index 00000000..7b75c648
--- /dev/null
+++ b/shared/src/commonMain/resources/MR/base/strings.xml
@@ -0,0 +1,3 @@
+
+ Hello, %s!
+
diff --git a/shared/src/commonTest/kotlin/co/nimblehq/kmm/template/commonTest.kt b/shared/src/commonTest/kotlin/co/nimblehq/kmm/template/commonTest.kt
deleted file mode 100644
index 560187be..00000000
--- a/shared/src/commonTest/kotlin/co/nimblehq/kmm/template/commonTest.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package co.nimblehq.kmm.template
-
-import kotlin.test.Test
-import kotlin.test.assertTrue
-
-class CommonGreetingTest {
-
- @Test
- fun testExample() {
- assertTrue(Greeting().greet().contains("Hello"), "Check 'Hello' is mentioned")
- }
-}
diff --git a/shared/src/iosMain/kotlin/co/nimblehq/kmm/template/Strings.kt b/shared/src/iosMain/kotlin/co/nimblehq/kmm/template/Strings.kt
new file mode 100644
index 00000000..4c9d3a8d
--- /dev/null
+++ b/shared/src/iosMain/kotlin/co/nimblehq/kmm/template/Strings.kt
@@ -0,0 +1,19 @@
+package co.nimblehq.kmm.template
+
+import dev.icerock.moko.resources.StringResource
+import dev.icerock.moko.resources.desc.Resource
+import dev.icerock.moko.resources.desc.StringDesc
+import dev.icerock.moko.resources.format
+
+actual class Strings {
+ actual fun get(
+ id: StringResource,
+ args: List,
+ ): String {
+ return if (args.isEmpty()) {
+ StringDesc.Resource(id).localized()
+ } else {
+ id.format(*args.toTypedArray()).localized()
+ }
+ }
+}
diff --git a/shared/src/iosTest/kotlin/co/nimblehq/kmm/template/iosTest.kt b/shared/src/iosTest/kotlin/co/nimblehq/kmm/template/iosTest.kt
deleted file mode 100644
index 3922db12..00000000
--- a/shared/src/iosTest/kotlin/co/nimblehq/kmm/template/iosTest.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package co.nimblehq.kmm.template
-
-import kotlin.test.Test
-import kotlin.test.assertTrue
-
-class IosGreetingTest {
-
- @Test
- fun testExample() {
- assertTrue(Greeting().greet().contains("iOS"), "Check iOS is mentioned")
- }
-}