Skip to content

Commit b3b8e6f

Browse files
authored
Merge pull request #143 from icerockdev/develop
Release 0.14.0
2 parents a295e03 + 1b97605 commit b3b8e6f

88 files changed

Lines changed: 3073 additions & 156 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 113 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ This is a Kotlin MultiPlatform library that provides access to the resources on
1717

1818
## Features
1919
- **Strings, Plurals, Images, Fonts, Files** to access the corresponding resources from common code;
20+
- **Colors** with light/dark mode support;
2021
- **StringDesc** for lifecycle-aware access to resources and unified localization on both platforms;
22+
- **Static** iOS frameworks support;
2123
- **FatFrameworkWithResourcesTask** Gradle task.
2224

2325
## Requirements
@@ -54,6 +56,7 @@ This is a Kotlin MultiPlatform library that provides access to the resources on
5456
- 0.13.1
5557
- kotlin 1.4.21
5658
- 0.13.2
59+
- 0.14.0
5760

5861
## Installation
5962
root build.gradle
@@ -64,7 +67,7 @@ buildscript {
6467
}
6568
6669
dependencies {
67-
classpath "dev.icerock.moko:resources-generator:0.13.2"
70+
classpath "dev.icerock.moko:resources-generator:0.14.0"
6871
}
6972
}
7073
@@ -81,7 +84,7 @@ project build.gradle
8184
apply plugin: "dev.icerock.mobile.multiplatform-resources"
8285
8386
dependencies {
84-
commonMainApi("dev.icerock.moko:resources:0.13.2")
87+
commonMainApi("dev.icerock.moko:resources:0.14.0")
8588
}
8689
8790
multiplatformResources {
@@ -121,6 +124,28 @@ multiplatformResources {
121124
}
122125
```
123126

127+
#### With Pods dependencies in Kotlin
128+
When you use `org.jetbrains.kotlin.native.cocoapods` plugin and also kotlin module depends to Pods -
129+
you also need to pass extra properties:
130+
```shell script
131+
"$SRCROOT/../gradlew" -p "$SRCROOT/../" :shared:copyFrameworkResourcesToApp \
132+
-Pmoko.resources.PLATFORM_NAME=$PLATFORM_NAME \
133+
-Pmoko.resources.CONFIGURATION=$CONFIGURATION \
134+
-Pmoko.resources.BUILT_PRODUCTS_DIR=$BUILT_PRODUCTS_DIR \
135+
-Pmoko.resources.CONTENTS_FOLDER_PATH=$CONTENTS_FOLDER_PATH\
136+
-Pkotlin.native.cocoapods.target=$KOTLIN_TARGET \
137+
-Pkotlin.native.cocoapods.configuration=$CONFIGURATION \
138+
-Pkotlin.native.cocoapods.cflags="$OTHER_CFLAGS" \
139+
-Pkotlin.native.cocoapods.paths.headers="$HEADER_SEARCH_PATHS" \
140+
-Pkotlin.native.cocoapods.paths.frameworks="$FRAMEWORK_SEARCH_PATHS"
141+
```
142+
and setup extra build settings in your xcode target:
143+
```
144+
'KOTLIN_TARGET[sdk=iphonesimulator*]' => 'ios_x64'
145+
'KOTLIN_TARGET[sdk=iphoneos*]' => 'ios_arm64'
146+
```
147+
[here example of changes](https://github.com/ln-12/moko-resources-issue-99/pull/2/files)
148+
124149
## Usage
125150
### Example 1 - simple localization string
126151
The first step is a create a file `strings.xml` in `commonMain/resources/MR/base` with the following content:
@@ -154,6 +179,33 @@ let string = getMyString().localized()
154179
```
155180
Note: `StringDesc` is a multiple-source container for Strings: in StringDesc we can use a resource, plurals, formatted variants, or raw string. To convert `StringDesc` to `String` on Android call `toString(context)` (a context is required for the resources usage), on iOS - call `localized()`.
156181

182+
#### MR directly from native side
183+
Android:
184+
```kotlin
185+
val string = MR.strings.my_string.desc().toString(context = this)
186+
```
187+
iOS:
188+
```swift
189+
let string = MR.strings.my_string.desc().localized()
190+
```
191+
192+
#### Get resourceId for Jetpack Compose / SwiftUI
193+
Android:
194+
```kotlin
195+
val resId = MR.strings.my_string.resourceId
196+
```
197+
for example in Compose:
198+
```kotlin
199+
text = stringResource(id = MR.strings.email.resourceId)
200+
```
201+
202+
iOS:
203+
```swift
204+
LocalizedStringKey(MR.strings.email.resourceId)
205+
```
206+
207+
Note: more info in issue [#126](https://github.com/icerockdev/moko-resources/issues/126).
208+
157209
### Example 2 - formatted localization string
158210
In `commonMain/resources/MR/base/strings.xml` add:
159211
```xml
@@ -326,6 +378,65 @@ We got autogenerated `MR.fonts.Raleway.italic`, `MR.fonts.Raleway.regular`, `MR.
326378
- Android: `textView.typeface = font.getTypeface(context = this)`
327379
- iOS: `textView.font = font.uiFont(withSize: 14.0)`
328380

381+
### Example 9 - pass colors
382+
Colors resources directory is `commonMain/resources/MR/colors`.
383+
Colors files is `xml` with format:
384+
```xml
385+
<?xml version="1.0" encoding="utf-8"?>
386+
<resources>
387+
<color name="valueColor">#B02743FF</color>
388+
<color name="referenceColor">@color/valueColor</color>
389+
<color name="themedColor">
390+
<light>0xB92743FF</light>
391+
<dark>7CCFEEFF</dark>
392+
</color>
393+
<color name="themedReferenceColor">
394+
<light>@color/valueColor</light>
395+
<dark>@color/referenceColor</dark>
396+
</color>
397+
</resources>
398+
```
399+
If you want use one color without light/dark theme selection:
400+
```xml
401+
<color name="valueColor">#B02743FF</color>
402+
```
403+
If you want use value of other color - use references:
404+
```xml
405+
<color name="referenceColor">@color/valueColor</color>
406+
```
407+
If you want different colors in light/dark themes:
408+
```xml
409+
<color name="themedColor">
410+
<light>0xB92743FF</light>
411+
<dark>7CCFEEFF</dark>
412+
</color>
413+
```
414+
Also themed colors can be referenced too:
415+
```xml
416+
<color name="themedReferenceColor">
417+
<light>@color/valueColor</light>
418+
<dark>@color/referenceColor</dark>
419+
</color>
420+
```
421+
422+
Colors available in common code insode `MR.colors.**` as `ColorResource`.
423+
`ColorResource` can be `ColorResource.Single` - simple color without theme selection.
424+
And can be `ColorResource.Themed` with colors for each mode.
425+
426+
You can read colors value from common code:
427+
```kotlin
428+
val color: Color = MR.colors.valueColor.color
429+
```
430+
but if you use `ColorResource.Themed` you can get current theme color only from platfrom side.
431+
Android:
432+
```kotlin
433+
val color: Color = MR.colors.valueColor.getColor(context = this)
434+
```
435+
iOS:
436+
```swift
437+
val color: UIColor = MR.colors.valueColor.getColor(UIScreen.main.traitCollection.userInterfaceStyle)
438+
```
439+
329440
### Gradle task for creating Fat Framework with resources
330441

331442
If you want to create Fat Framework for iOS with all resources from KMP Gradle module you should use

buildSrc/src/main/kotlin/Deps.kt

100755100644
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ object Deps {
1919

2020
private const val mokoGraphicsVersion = "0.5.0"
2121
private const val mokoParcelizeVersion = "0.5.0"
22-
const val mokoResourcesVersion = "0.13.2"
22+
const val mokoResourcesVersion = "0.14.0"
2323

2424
object Android {
2525
const val compileSdk = 28
@@ -35,12 +35,12 @@ object Deps {
3535
val kotlinMultiplatform = GradlePlugin(id = "org.jetbrains.kotlin.multiplatform")
3636
val kotlinKapt = GradlePlugin(id = "kotlin-kapt")
3737
val kotlinAndroid = GradlePlugin(id = "kotlin-android")
38-
val kotlinAndroidExtensions = GradlePlugin(id = "kotlin-android-extensions")
38+
val kotlinParcelize = GradlePlugin(id = "kotlin-parcelize")
3939
val kotlinSerialization = GradlePlugin(id = "kotlin-serialization")
4040
val mavenPublish = GradlePlugin(id = "org.gradle.maven-publish")
4141

4242
val mobileMultiplatform = GradlePlugin(id = "dev.icerock.mobile.multiplatform")
43-
val iosFramework = GradlePlugin(id = "dev.icerock.mobile.multiplatform.ios-framework")
43+
val appleFramework = GradlePlugin(id = "dev.icerock.mobile.multiplatform.apple-framework")
4444

4545
val mokoResources = GradlePlugin(
4646
id = "dev.icerock.mobile.multiplatform-resources",
@@ -80,7 +80,7 @@ object Deps {
8080
const val mokoResources = "dev.icerock.moko:resources:$mokoResourcesVersion"
8181
const val mokoParcelize = "dev.icerock.moko:parcelize:$mokoParcelizeVersion"
8282
val mokoGraphics = "dev.icerock.moko:graphics:$mokoGraphicsVersion"
83-
.defaultMPL(ios = true)
83+
.defaultMPL(android = true, ios = true, macos = true)
8484

8585
object Tests {
8686
const val kotlinTest =

plugins/resources-generator/src/main/kotlin/dev/icerock/gradle/MultiplatformResourcesPlugin.kt

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
package dev.icerock.gradle
66

7-
import com.android.build.gradle.LibraryExtension
8-
import com.android.build.gradle.LibraryPlugin
7+
import com.android.build.gradle.BaseExtension
8+
import com.android.build.gradle.BasePlugin
99
import com.android.build.gradle.api.AndroidSourceSet
1010
import dev.icerock.gradle.generator.ColorsGenerator
1111
import dev.icerock.gradle.generator.FilesGenerator
@@ -18,7 +18,7 @@ import dev.icerock.gradle.generator.SourceInfo
1818
import dev.icerock.gradle.generator.StringsGenerator
1919
import dev.icerock.gradle.generator.android.AndroidMRGenerator
2020
import dev.icerock.gradle.generator.common.CommonMRGenerator
21-
import dev.icerock.gradle.generator.ios.IosMRGenerator
21+
import dev.icerock.gradle.generator.apple.AppleMRGenerator
2222
import dev.icerock.gradle.tasks.GenerateMultiplatformResourcesTask
2323
import org.gradle.api.Plugin
2424
import org.gradle.api.Project
@@ -30,39 +30,43 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
3030
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
3131
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
3232
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
33-
import org.jetbrains.kotlin.konan.target.Family
3433
import org.jetbrains.kotlin.konan.target.HostManager
3534
import java.io.File
3635
import javax.xml.parsers.DocumentBuilderFactory
3736

3837
class MultiplatformResourcesPlugin : Plugin<Project> {
3938
override fun apply(target: Project) {
4039
val mrExtension =
41-
target.extensions.create("multiplatformResources", MultiplatformResourcesPluginExtension::class.java)
40+
target.extensions.create(
41+
"multiplatformResources",
42+
MultiplatformResourcesPluginExtension::class.java
43+
)
4244

4345
target.plugins.withType(KotlinMultiplatformPluginWrapper::class.java) {
44-
val multiplatformExtension = target.extensions.getByType(KotlinMultiplatformExtension::class.java)
46+
val multiplatformExtension =
47+
target.extensions.getByType(KotlinMultiplatformExtension::class.java)
4548

46-
target.plugins.withType(LibraryPlugin::class.java) {
47-
val androidExtension = target.extensions.getByName("android") as LibraryExtension
49+
target.plugins.withType(BasePlugin::class.java) {
50+
val extension = it.getExtension()
4851

4952
target.afterEvaluate {
5053
configureGenerators(
5154
target = target,
5255
mrExtension = mrExtension,
5356
multiplatformExtension = multiplatformExtension,
54-
androidExtension = androidExtension
57+
androidExtension = extension
5558
)
5659
}
5760
}
5861
}
5962
}
6063

64+
@Suppress("LongMethod")
6165
private fun configureGenerators(
6266
target: Project,
6367
mrExtension: MultiplatformResourcesPluginExtension,
6468
multiplatformExtension: KotlinMultiplatformExtension,
65-
androidExtension: LibraryExtension
69+
androidExtension: BaseExtension
6670
) {
6771
val androidMainSourceSet =
6872
androidExtension.sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
@@ -95,7 +99,13 @@ class MultiplatformResourcesPlugin : Plugin<Project> {
9599
)
96100
val targets: List<KotlinTarget> = multiplatformExtension.targets.toList()
97101

98-
setupCommonGenerator(commonSourceSet, generatedDir, mrClassPackage, features, target)
102+
val commonGenerationTask = setupCommonGenerator(
103+
commonSourceSet = commonSourceSet,
104+
generatedDir = generatedDir,
105+
mrClassPackage = mrClassPackage,
106+
features = features,
107+
target = target
108+
)
99109
setupAndroidGenerator(
100110
targets,
101111
androidMainSourceSet,
@@ -105,7 +115,7 @@ class MultiplatformResourcesPlugin : Plugin<Project> {
105115
target
106116
)
107117
if (HostManager.hostIsMac) {
108-
setupIosGenerator(
118+
setupAppleGenerator(
109119
targets,
110120
generatedDir,
111121
mrClassPackage,
@@ -118,7 +128,6 @@ class MultiplatformResourcesPlugin : Plugin<Project> {
118128
}
119129

120130
val generationTasks = target.tasks.filterIsInstance<GenerateMultiplatformResourcesTask>()
121-
val commonGenerationTask = generationTasks.first { it.name == "generateMRcommonMain" }
122131
generationTasks.filter { it != commonGenerationTask }
123132
.forEach { it.dependsOn(commonGenerationTask) }
124133
}
@@ -129,9 +138,9 @@ class MultiplatformResourcesPlugin : Plugin<Project> {
129138
mrClassPackage: String,
130139
features: List<ResourceGeneratorFeature<out MRGenerator.Generator>>,
131140
target: Project
132-
) {
141+
): GenerateMultiplatformResourcesTask {
133142
val commonGeneratorSourceSet: MRGenerator.SourceSet = createSourceSet(commonSourceSet)
134-
CommonMRGenerator(
143+
return CommonMRGenerator(
135144
generatedDir,
136145
commonGeneratorSourceSet,
137146
mrClassPackage,
@@ -165,7 +174,7 @@ class MultiplatformResourcesPlugin : Plugin<Project> {
165174
}
166175

167176
@Suppress("LongParameterList")
168-
private fun setupIosGenerator(
177+
private fun setupAppleGenerator(
169178
targets: List<KotlinTarget>,
170179
generatedDir: File,
171180
mrClassPackage: String,
@@ -175,7 +184,7 @@ class MultiplatformResourcesPlugin : Plugin<Project> {
175184
) {
176185
val compilations = targets
177186
.filterIsInstance<KotlinNativeTarget>()
178-
.filter { it.konanTarget.family == Family.IOS }
187+
.filter { it.konanTarget.family.isAppleFamily }
179188
.map { kotlinNativeTarget ->
180189
kotlinNativeTarget.compilations
181190
.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
@@ -187,7 +196,7 @@ class MultiplatformResourcesPlugin : Plugin<Project> {
187196
val depend = kss.getDependedFrom(defSourceSets)
188197

189198
val sourceSet = createSourceSet(depend ?: kss)
190-
IosMRGenerator(
199+
AppleMRGenerator(
191200
generatedDir,
192201
sourceSet,
193202
mrClassPackage,

plugins/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/ColorsGenerator.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import com.squareup.kotlinpoet.PropertySpec
1212
import com.squareup.kotlinpoet.TypeSpec
1313
import dev.icerock.gradle.generator.android.AndroidColorsGenerator
1414
import dev.icerock.gradle.generator.common.CommonColorsGenerator
15-
import dev.icerock.gradle.generator.ios.IosColorsGenerator
15+
import dev.icerock.gradle.generator.apple.AppleColorsGenerator
1616
import org.gradle.api.file.FileTree
1717
import java.io.File
1818
import javax.xml.parsers.DocumentBuilderFactory
@@ -141,7 +141,7 @@ abstract class ColorsGenerator(
141141
}
142142

143143
override fun createIosGenerator(): ColorsGenerator {
144-
return IosColorsGenerator(
144+
return AppleColorsGenerator(
145145
colorsFileTree
146146
)
147147
}

plugins/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/FilesGenerator.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import com.squareup.kotlinpoet.PropertySpec
1111
import com.squareup.kotlinpoet.TypeSpec
1212
import dev.icerock.gradle.generator.android.AndroidFilesGenerator
1313
import dev.icerock.gradle.generator.common.CommonFilesGenerator
14-
import dev.icerock.gradle.generator.ios.IosFilesGenerator
14+
import dev.icerock.gradle.generator.apple.AppleFilesGenerator
1515
import org.gradle.api.file.FileTree
1616
import java.io.File
1717

@@ -90,7 +90,7 @@ abstract class FilesGenerator(
9090
}
9191

9292
override fun createIosGenerator(): FilesGenerator {
93-
return IosFilesGenerator(fileTree)
93+
return AppleFilesGenerator(fileTree)
9494
}
9595

9696
override fun createAndroidGenerator(): FilesGenerator {

plugins/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/FontsGenerator.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import com.squareup.kotlinpoet.PropertySpec
1111
import com.squareup.kotlinpoet.TypeSpec
1212
import dev.icerock.gradle.generator.android.AndroidFontsGenerator
1313
import dev.icerock.gradle.generator.common.CommonFontsGenerator
14-
import dev.icerock.gradle.generator.ios.IosFontsGenerator
14+
import dev.icerock.gradle.generator.apple.AppleFontsGenerator
1515
import org.gradle.api.file.FileTree
1616
import java.io.File
1717

@@ -117,7 +117,7 @@ abstract class FontsGenerator(
117117
}
118118

119119
override fun createIosGenerator(): FontsGenerator {
120-
return IosFontsGenerator(stringsFileTree)
120+
return AppleFontsGenerator(stringsFileTree)
121121
}
122122

123123
override fun createAndroidGenerator(): FontsGenerator {

0 commit comments

Comments
 (0)