Git Product home page Git Product logo

moko-resources's Issues

Build fails if it is not running on MacOS

Execution failed for task ':mppLibrary:generateMRiosMain'.
Caused by: org.gradle.api.UncheckedIOException: java.io.IOException: Cannot run program "xcrun" (in directory "/home/.../mppLibrary/build/generated/moko/iosMain/res"): error=2, No such file or directory

I fix this by checking the OS, but I think it would be logical to embed something like this in the plugin :)

tasks.whenTaskAdded {
    if (name == "generateMRiosMain") onlyIf {
        org.gradle.internal.os.OperatingSystem.current()!!.isMacOsX
    }
}

More samples of StringDesc usage

Need more samples of StringDesc in main use cases:

  • mixed source (resources or raw data)
  • lifecycle handling
  • creating from StringResource / PluralResource / Int (on android)

Drawables generation in MR gradle-plugin

Add in gradle-plugin support of drawables object generation with DrawableResources and placing image assets to correct folders:
android: drawable (for vector), drawable-**dpi (for bitmaps)
ios: Assets.xcassets directory & compilation of directory (not confirmed that it necessary, but should be researched)

Can't link iOS framework in offline

when try link in offline got:

Execution failed for task ':mpp-library:linkMultiPlatformLibraryDebugFrameworkIosX64'.
> java.net.UnknownHostException: www.apple.com

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':mpp-library:linkMultiPlatformLibraryDebugFrameworkIosX64'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.accept(ExecuteActionsTaskExecuter.java:148)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.accept(ExecuteActionsTaskExecuter.java:145)
        at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:191)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:138)
        at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionStateTaskExecuter.execute(ResolveBeforeExecutionStateTaskExecuter.java:75)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:62)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:108)
        at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionOutputsTaskExecuter.execute(ResolveBeforeExecutionOutputsTaskExecuter.java:67)
        at org.gradle.api.internal.tasks.execution.StartSnapshotTaskInputsBuildOperationTaskExecuter.execute(StartSnapshotTaskInputsBuildOperationTaskExecuter.java:62)
        at org.gradle.api.internal.tasks.execution.ResolveAfterPreviousExecutionStateTaskExecuter.execute(ResolveAfterPreviousExecutionStateTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:94)
        at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:95)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:73)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:49)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:49)
        at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: org.gradle.api.UncheckedIOException: java.net.UnknownHostException: www.apple.com
        at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:61)
        at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:41)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$5.run(ExecuteActionsTaskExecuter.java:431)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:390)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:373)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:79)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:210)
        at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$1(ExecuteStep.java:33)
        at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:33)
        at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
        at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:58)
        at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:35)
        at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:48)
        at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:33)
        at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:39)
        at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)
        at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)
        at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:35)
        at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
        at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:45)
        at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:31)
        at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:201)
        at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:70)
        at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:45)
        at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49)
        at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:43)
        at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:32)
        at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)
        at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)
        at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:96)
        at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:89)
        at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:54)
        at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:38)
        at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:77)
        at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)
        at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)
        at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)
        at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:90)
        at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:48)
        at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:117)
        ... 36 more
Caused by: java.net.UnknownHostException: www.apple.com
        at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:647)
        at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1304)
        at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(XMLEntityManager.java:1270)
        at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(XMLDTDScannerImpl.java:259)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1162)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1045)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:959)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
        at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
        at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
        at dev.icerock.gradle.generator.IosMRGenerator$apply$$inlined$forEach$lambda$1.execute(IosMRGenerator.kt:79)
        at dev.icerock.gradle.generator.IosMRGenerator$apply$$inlined$forEach$lambda$1.execute(IosMRGenerator.kt:26)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:702)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:669)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$5.run(ExecuteActionsTaskExecuter.java:401)
        ... 81 more


* Get more help at https://help.gradle.org

Error at

detekt not work on CI

detekt not see sources of plugin on CI:
> Task :gradle-plugin:detekt NO-SOURCE
maybe it not work at all on this project. need fix

Shared file resources

Implementation of a feature to share resource files or assets (e.g. config file) from same location for both platforms and for native and common code (if it's possible) is needed.

Update readme

  • logo (?)
  • description with goals
  • gif with clear example in action
  • features - strings, plurals, drawables resources support. StringDesc for lifecycle aware resources access
  • simple usage
  • installation steps
  • detailed usage
  • how to contribute
  • license block

Support multiple strings files

In Android development, it is quite convenient for larger apps to separate string resources by module/logical unit. Sample would be a common strings.xml, and then strings-about.xml, strings-settings.xml etc.

It would be great for moko resources to support this as well, as it helps organize strings in larger apps with lots of strings.

Cannot access class 'dev.icerock.moko.resources.desc.StringDesc'

Hello,
i followed the sample project implementation of this library; but when i try to run android app i get this error.
Cannot access class 'dev.icerock.moko.resources.desc.StringDesc'. Check your module classpath for missing or conflicting dependencies.

equals no longer working correctly on StringDesc

With the recent changes in #62 the various StringDesc subclasses are now no longer data classes so the equals method is now no longer comparing based on the properties, which is causing our tests to fail.

So before this would be true and now is false because of this:

"a".desc() == "a".desc()

Allow for source set overrides

Thanks for your work on this library, it's great. Would you consider tweaking the gradle plugin to allow for overriding of commonMain as the base source set? Along the lines of dgluhovic@a19d126 . This works for my purpose, would be happy to submit a PR if not too hacky. My use case is, commonMain contains models, constants etc, shared with a backend jvm target not supported by MR. Shared client code is in commonClientMain, would like to set this as the MR base source set.

Can't access files from Swift

Hello!

This is a very similar issue to #80 .
Regardless, it is being added as Embed&Sign and yet, when I try to access the files through the debugger, I get this:

(lldb) p MR.files().testfile
error: Execution was interrupted, reason: internal c++ exception breakpoint(-4)..
The process has been returned to the state before expression evaluation.
(lldb) p MR.files().testfile
(ResourcesFileResource) $R0 = <uninitialized>
(lldb) p MR.files().testfile()
(String) $R2 = ""
(lldb) 

If I try to access it through the Kotlin MPP shared code, a NullPointerException is guaranteed:

0   KotlinMPPClient                         0x0000000106878d2e kfun:kotlin.Throwable.<init>()kotlin.Throwable + 62
1   KotlinMPPClient                         0x000000010686b8a7 kfun:kotlin.Exception.<init>()kotlin.Exception + 55
2   KotlinMPPClient                         0x000000010686bac7 kfun:kotlin.RuntimeException.<init>()kotlin.RuntimeException + 55
3   KotlinMPPClient                         0x000000010686bce7 kfun:kotlin.NullPointerException.<init>()kotlin.NullPointerException + 55
4   KotlinMPPClient                         0x00000001068ee0e7 ThrowNullPointerException + 119
5   KotlinMPPClient                         0x00000001075dbd47 kfun:dev.icerock.moko.resources.utils.loadableBundle@platform.Foundation.NSBundle.Companion.(kotlin.String)platform.Foundation.NSBundle + 4951
6   KotlinMPPClient                         0x0000000106347302 kfun:com.romeu.project.MR.<init>$lambda-0#internal + 162
7   KotlinMPPClient                         0x0000000106347424 kfun:com.romeu.project.MR.$<init>$lambda-0$FUNCTION_REFERENCE$1.invoke#internal + 132
8   KotlinMPPClient                         0x00000001068c494c kfun:kotlin.native.concurrent.FreezeAwareLazyImpl.getOrInit#internal + 1004
9   KotlinMPPClient                         0x00000001068c5079 kfun:kotlin.native.concurrent.FreezeAwareLazyImpl.<get-value>()T + 393
10  KotlinMPPClient                         0x0000000106346093 kfun:com.romeu.project.MR.<get-bundle>#internal + 323
11  KotlinMPPClient                         0x0000000106346a1b kfun:com.romeu.project.MR.files.<init>()com.romeu.project.MR.files + 427
12  KotlinMPPClient                         0x0000000106c9fb55 InitSharedInstanceStrict + 197
13  KotlinMPPClient                         0x00000001064d079f kfun:com.romeu.project.utils.getResourceFileAsText(com.romeu.project.utils.ResourceMocks)kotlin.String + 1359
14  KotlinMPPClient                         0x000000010639f9e0 kfun:data.manager.Repository.$getFileStringCOROUTINE$28.invokeSuspend(kotlin.Result<kotlin.Any?>)kotlin.Any? + 24960
15  KotlinMPPClient                         0x00000001063a08ab kfun:data.manager.Repository.getFileString(kotlin.Int)kotlin.collections.List<data.models.MyChannel> + 283
16  KotlinMPPClient                         0x00000001063524eb kfun:KotlinMPPClient.$getFileString$lambda-4COROUTINE$3.invokeSuspend#internal + 1291
17  KotlinMPPClient                         0x0000000106352d7c kfun:KotlinMPPClient.$getFileString$lambda-4COROUTINE$3.invoke#internal + 268
18  KotlinMPPClient                         0x0000000106364e5a kfun:KotlinMPPClient.$executeRequest$<anonymous>_3COROUTINE$21.invokeSuspend#internal + 2730
19  KotlinMPPClient                         0x00000001068a4e88 kfun:kotlin.coroutines.native.internal.BaseContinuationImpl.resumeWith(kotlin.Result<kotlin.Any?>) + 712
20  KotlinMPPClient                         0x0000000106f0af66 kfun:kotlinx.coroutines.DispatchedTask.run() + 2614
21  KotlinMPPClient                         0x00000001064cba08 kfun:com.romeu.project.NsQueueDispatcher.dispatch$lambda-0#internal + 88
22  KotlinMPPClient                         0x00000001064cbafe kfun:com.romeu.project.NsQueueDispatcher.$dispatch$lambda-0$FUNCTION_REFERENCE$4.invoke#internal + 62
23  KotlinMPPClient                         0x00000001064cbb5e kfun:com.romeu.project.NsQueueDispatcher.$dispatch$lambda-0$FUNCTION_REFERENCE$4.$<bridge-UNN>invoke()#internal + 62
24  KotlinMPPClient                         0x00000001064cbc47 _6d656f676f73646b_knbridge22 + 183
25  libdispatch.dylib                         0x000000010f8719da _dispatch_call_block_and_release + 12
26  libdispatch.dylib                         0x000000010f872bb6 _dispatch_client_callout + 8
27  libdispatch.dylib                         0x000000010f881050 _dispatch_main_queue_callback_4CF + 1152
28  CoreFoundation                        0x000000010a9e6b8b __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
29  CoreFoundation                        0x000000010a9e16ad __CFRunLoopRun + 2111

Everything works fine on Android and in both platforms the MR stuff generation is done.

What could be causing this?

Thanks.

Edit:

It seems the NullPointerException comes from loadableBundle() extension from Moko-Resources.
But I do not know which line specifically. Could be return NSBundle.bundleWithIdentifier(identifier)!!.

I should also say that the iOS app is being ran on iOS 14.

Unable to resolve dependency in Kotlin MPP

Hello.

I am trying to integrate this library into a project and in iOS, Gradle gives the following error:

Could not determine the dependencies of task ':project:linkDebugFrameworkIosArm32'.
> Could not resolve all task dependencies for configuration ':project:iosArm32CompileKlibraries'.
   > Could not resolve dev.icerock.moko:resources:0.11.0.
     Required by:
         project :project
      > Unable to find a matching variant of dev.icerock.moko:resources:0.11.0:
          - Variant 'android-debugApiElements' capability dev.icerock.moko:resources:0.11.0:
              - Incompatible attribute:
                  - Required org.jetbrains.kotlin.platform.type 'native' and found incompatible value 'androidJvm'.
              - Other attributes:
                  - Found com.android.build.api.attributes.BuildTypeAttr 'debug' but wasn't required.
                  - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
                  - Found com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' but wasn't required.
                  - Found org.gradle.status 'release' but wasn't required.
                  - Required org.gradle.usage 'kotlin-api' and found compatible value 'java-api'.
                  - Required org.jetbrains.kotlin.native.target 'ios_arm32' but no value provided.
          - Variant 'android-debugRuntimeElements' capability dev.icerock.moko:resources:0.11.0:
              - Incompatible attribute:
                  - Required org.jetbrains.kotlin.platform.type 'native' and found incompatible value 'androidJvm'.
              - Other attributes:
                  - Found com.android.build.api.attributes.BuildTypeAttr 'debug' but wasn't required.
                  - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
                  - Found com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' but wasn't required.
                  - Found org.gradle.status 'release' but wasn't required.
                  - Required org.gradle.usage 'kotlin-api' and found compatible value 'java-runtime'.
                  - Required org.jetbrains.kotlin.native.target 'ios_arm32' but no value provided.
          - Variant 'android-releaseApiElements' capability dev.icerock.moko:resources:0.11.0:
              - Incompatible attribute:
                  - Required org.jetbrains.kotlin.platform.type 'native' and found incompatible value 'androidJvm'.
              - Other attributes:
                  - Found com.android.build.api.attributes.BuildTypeAttr 'release' but wasn't required.
                  - Found com.android.build.api.attributes.VariantAttr 'release' but wasn't required.
                  - Found com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' but wasn't required.
                  - Found org.gradle.status 'release' but wasn't required.
                  - Required org.gradle.usage 'kotlin-api' and found compatible value 'java-api'.
                  - Required org.jetbrains.kotlin.native.target 'ios_arm32' but no value provided.
          - Variant 'android-releaseRuntimeElements' capability dev.icerock.moko:resources:0.11.0:
              - Incompatible attribute:
                  - Required org.jetbrains.kotlin.platform.type 'native' and found incompatible value 'androidJvm'.
              - Other attributes:
                  - Found com.android.build.api.attributes.BuildTypeAttr 'release' but wasn't required.
                  - Found com.android.build.api.attributes.VariantAttr 'release' but wasn't required.
                  - Found com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' but wasn't required.
                  - Found org.gradle.status 'release' but wasn't required.
                  - Required org.gradle.usage 'kotlin-api' and found compatible value 'java-runtime'.
                  - Required org.jetbrains.kotlin.native.target 'ios_arm32' but no value provided.
          - Variant 'iosArm64-api' capability dev.icerock.moko:resources:0.11.0:
              - Incompatible attribute:
                  - Required org.jetbrains.kotlin.native.target 'ios_arm32' and found incompatible value 'ios_arm64'.
              - Other attributes:
                  - Found org.gradle.status 'release' but wasn't required.
                  - Required org.gradle.usage 'kotlin-api' and found compatible value 'kotlin-api'.
                  - Required org.jetbrains.kotlin.platform.type 'native' and found compatible value 'native'.
          - Variant 'iosX64-api' capability dev.icerock.moko:resources:0.11.0:
              - Incompatible attribute:
                  - Required org.jetbrains.kotlin.native.target 'ios_arm32' and found incompatible value 'ios_x64'.
              - Other attributes:
                  - Found org.gradle.status 'release' but wasn't required.
                  - Required org.gradle.usage 'kotlin-api' and found compatible value 'kotlin-api'.
                  - Required org.jetbrains.kotlin.platform.type 'native' and found compatible value 'native'.
          - Variant 'metadata-api' capability dev.icerock.moko:resources:0.11.0:
              - Incompatible attribute:
                  - Required org.jetbrains.kotlin.platform.type 'native' and found incompatible value 'common'.
              - Other attributes:
                  - Found org.gradle.status 'release' but wasn't required.
                  - Required org.gradle.usage 'kotlin-api' and found compatible value 'kotlin-api'.
                  - Required org.jetbrains.kotlin.native.target 'ios_arm32' but no value provided.
   > Could not resolve dev.icerock.moko:resources-iosarm64:0.11.0.
     Required by:
         project :project
      > Unable to find a matching variant of dev.icerock.moko:resources-iosarm64:0.11.0:
          - Variant 'iosArm64-api' capability dev.icerock.moko:resources-iosarm64:0.11.0:
              - Incompatible attribute:
                  - Required org.jetbrains.kotlin.native.target 'ios_arm32' and found incompatible value 'ios_arm64'.
              - Other attributes:
                  - Found org.gradle.status 'release' but wasn't required.
                  - Required org.gradle.usage 'kotlin-api' and found compatible value 'kotlin-api'.
                  - Required org.jetbrains.kotlin.platform.type 'native' and found compatible value 'native'.
          - Variant 'metadata-api' capability dev.icerock.moko:resources-iosarm64:0.11.0:
              - Incompatible attribute:
                  - Required org.jetbrains.kotlin.platform.type 'native' and found incompatible value 'common'.
              - Other attributes:
                  - Found org.gradle.status 'release' but wasn't required.
                  - Required org.gradle.usage 'kotlin-api' and found compatible value 'kotlin-api'.

My Gradle file, although being in Groovy, it seems to be pretty much correct?

apply plugin: 'com.android.library'
apply plugin: 'org.jetbrains.kotlin.multiplatform'
apply plugin: 'kotlinx-serialization'
apply plugin: 'org.jetbrains.kotlin.native.cocoapods'
apply plugin: "dev.icerock.mobile.multiplatform-resources"


android {
    compileSdkVersion 28

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 28
    }

    sourceSets {
        main {
            setRoot('src/androidMain')
        }
        release {
            setRoot('src/androidMainRelease')
        }
        debug {
            setRoot('src/androidMainDebug')
        }
        test {
            setRoot('src/androidUnitTest')
        }
        testRelease {
            setRoot('src/androidUnitTestRelease')
        }
        testDebug {
            setRoot('src/androidUnitTestDebug')
        }
    }
}

kotlin {

    version = "0.0.1"

    android("android")

    targets {
        final def buildForDevice = project.findProperty("kotlin.native.cocoapods.target") == "ios_arm"
        if (buildForDevice) {
            iosArm64("iosArm64")
            iosArm32("iosArm32")
        } else {
            iosX64("ios")
        }
    }

    sourceSets {
        commonMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"

                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version"

                // resources
                implementation "dev.icerock.moko:resources:$moko_resources_version"
            }
        }

        androidMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

                implementation "io.ktor:ktor-client-android:$ktor_version"
                implementation "io.ktor:ktor-client-okhttp:$ktor_version"
                implementation "io.ktor:ktor-client-serialization-jvm:$ktor_version"

                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"

                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version"
            }
        }

        iosMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"

                // resources
                implementation "dev.icerock.moko:resources-iosarm64:$moko_resources_version"
            }
        }

        iosArm32Main {
            dependsOn iosMain
        }

        iosArm64Main {
            dependsOn iosMain
        }
    }

    cocoapods {
        //version = "0.1.0" // Defaults to "1.0.0-LOCAL"
        homepage = "www.example.com"  // Default to empty
        summary = "..." // Defaults to empty
        frameworkName = "project"
    }

}

multiplatformResources {
    multiplatformResourcesPackage = "com.project.app"
    //iosBaseLocalizationRegion = "en" //optional, default "en"
    //multiplatformResourcesSourceSet = "commonClientMain"  // optional, default "commonMain"
}

I also have enableFeaturePreview("GRADLE_METADATA") in my settings.gradle, removing it causes some problems.
Also, it works well on Android.

Any clues?

Thanks

Automatically lowercase android resources filenames

Now for image names like 'logoutIcon.png' android show error:

'I' is not a valid file-based resource name character: File-based resource names must contain only lowercase a-z, 0-9, or underscore

we should automatically convert common resource name to valid on platform side

Help to get localization to work on iOS

Hi, I setup the library according to the documentation in version 0.9.0 and kotlin 1.3.70.

Now on Android, everything works as expected and I can localize my strings. On iOS though, only the translation key is displayed.

shared lib build.gradle.kts

kotlin {
    //select iOS target platform depending on the Xcode environment variables
    val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
        if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
            ::iosArm64
        else
            ::iosX64

    iOSTarget("ios") {
        binaries {
            framework {
                baseName = "MyLibShared"
                export("dev.icerock.moko:resources:${Versions.Libs.MultiPlatform.mokoResources}")
            }
        }
    }
}
...
multiplatformResources {
    multiplatformResourcesPackage = "jp.mylib.shared"
}

I verified the framework is correctly created and contains the localized files:
Screen Shot 2020-04-01 at 11 59 11

I tried a coupl of approaches to get the string:

// in swift; does not work
Localizer().getMyString().localized() // displays "my_string"
// shared code in iosMain: Localizer object: fun getMyString(): StringDesc = StringDesc.Resource(MR.strings.my_string)

// in swift; does not work; unresolved StringDesc
StringDesc.Resource(MR.strings.my_string).localize()

// in swift; this works though, so the files are loaded
NSLocalizedString("my_string", tableName: nil, bundle: Bundle(identifier: "jp.mylib.shared.MyLibShared")!, value: "", comment: "") // displays "My String!"

Do you have an idea on what the issue could be? Any pointer?

Incorrect generation for strings with special characters

For string with char &, encoded with &amp

    <string name="sell.selectMethod.choosePortfolioAmount">CHOOSE PORTFOLIO &amp; AMOUNT</string>

generated line looks like

    <string name="sell.selectMethod.choosePortfolioAmount">CHOOSE PORTFOLIO & AMOUNT</string>

Android platform get compilation error with this line because of & symbol without encoding

Error when building my project

I get the following error:
`> Task :SDK:compileKotlinIos FAILED
w: skipping /Users/dev/.gradle/caches/modules-2/files-2.1/dev.icerock.moko/resources-iosx64/0.9.0/b3ee2c301a8ab2048c8261ebc92c854fa7698d6d/resources.klib. The abi versions don't match. Expected '[17]', found '22'

w: The compiler versions don't match either. Expected '[]', found '1.3.70-release'

e: Could not find "/Users/dev/.gradle/caches/modules-2/files-
2.1/dev.icerock.moko/resources-iosx64/0.9.0/b3ee2c301a8ab2048c8261ebc92c854fa7698d6d/resources.klib" in [/Users/dev/development/my-project/SDK, /Users/dev/.konan/klib, /Users/dev/.konan/kotlin-native-macos-1.3.61/klib/common, /Users/dev/.konan/kotlin-native-macos-1.3.61/klib/platform/ios_x6`

What might be happening?

MR file generator

gradle plugin for MR object generation contains:

  • strings
  • plurals

later - drawables (for now just add to sample how store drawable resources)

plugin should generate from one strings, plurals localized source in commonMain platform-specific resources (android - strings.xml, ios - Localizable.string) and attach to multiplatform project output

Add a StringDesc type that is a wrapper transform

I have a case where I want to return something like a StringDesc to the UI so that it only has to call localized or toString(context) but where a transformation is ran on the result. The particular case is I have a String defining a date format and the transformation I want to run is use that format as an argument to a format call. I want to define that in common code so it does not know about loacalized or toString(context) and I don't want the code that receives it to have to call the format method.

I would try to define it myself but the fact that StringDesc is sealed makes that impossible

So what I am proposing is a map extension method on StringDesc. So I envision this in the common code:

return MR.strings.my_date_format.desc().map { myDate.format(it).desc() }

So in StringDesc you would need a new class:

class Mapped(stringDesc: StringDesc, transform: (String) -> StringDesc) : StringDesc

You would need extension methods on StringDesc:

fun StringDesc.map(transform: (String) -> StringDesc) = StringDesc.Mapped(this, transform)

And then the Android implementation might be:

 actual data class Mapped actual constructor(
     val stringDesc: StringDesc,
     val transform: (String) -> StringDesc
 ) : StringDesc() {
     override fun toString(context: Context) =
        stringDesc.toString(context).let(transform).toString(context)
 }

Accessing MR strings from Swift

Hi!

I'm testing this plugin and everything works fine, but, from XCode I'm not able to access to MR.strings. values

I would like to use them directly to for passing it as parameter to a Shared function.

Is this possible?

Thanks for your effort!

Formatted strings doesn't work properly

I have formatted string in my multiplatform strings that look like:

<string name="myString">%s from %s</string>

When I'm trying to get this string with this code:

StringDesc.ResourceFormatted(MR.strings.myString, arg1, arg2).toString(context)
(arg1 and arg2 are Int)

I'm getting this error:

 java.util.MissingFormatArgumentException: Format specifier '%s'
        at java.util.Formatter.format(Formatter.java:2522)
        at java.util.Formatter.format(Formatter.java:2458)
        at java.lang.String.format(String.java:2883)
        at android.content.res.Resources.getString(Resources.java:481)
        at dev.icerock.moko.resources.desc.ResourceFormattedStringDesc.toString(ResourceFormattedStringDesc.kt:16)
        at co.getfullstack.skill.presentation.common.ResourceProvider.getString(ResourceProvider.kt:29)

Also if I remove one of format argument from my string I will receive strings like this one:
"[Ljava.lang.Object;@6b0dc06 from".

Also, I've tried some variants of string:

  • <string name="myString">%d from %d</string> - java.util.IllegalFormatConversionException: d != [Ljava.lang.Object;, even if I pass Int value.
  • <string name="myString">%1$s from %2$s</string> - java.util.MissingFormatArgumentException: Format specifier '%2$s'

OS: Android
Lib version: 0.9.1, 0.10.0
Kotlin: 1.3.71

Localized strings is not available on iOS if iOS-framework was compiled by Gradle FatFramework task

When I use Gradle FatFramework task, I can't see any of my localized strings on iOS side
The task I use to compile my framework:

val fatFramework by tasks.creating(FatFrameworkTask::class) {
    baseName = "multiplatform"

    val targets = listOf(
            kotlin.targets.getByName<KotlinNativeTarget>("iosX64"),
            kotlin.targets.getByName<KotlinNativeTarget>("iosArm64")
    )

    from(targets.map { it.binaries.getFramework("DEBUG") })
}

If I change it to Gradle Sync task it works as expected (I see all my strings on iOS side):

val syncFramework by tasks.creating(Sync::class) {
    val targetDir = File(buildDir, "frameworks")
    val mode = "DEBUG"
    val framework = kotlin.targets
            .getByName<KotlinNativeTarget>("ios")
            .binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)
    from({ framework.outputDirectory })
    into(targetDir)
}

Kotlin 1.3.72, moko-resources 0.10.0 (had the same issue on 0.9.1)

Do you have any ideas what a cause of the issue? And am I able to fix it?

Custom fonts resources

Required for icerockdev/moko-widgets#6

in commonMain/resources/fonts should be placed custom fonts like:

  • commonMain/resources/fonts/MyFont-regular.ttf
  • commonMain/resources/fonts/MyFont-italic.ttf

and generated into:

object MR {
  object fonts {
    val myFont: FontResource
  }
}

Links:
https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml
https://developer.apple.com/documentation/uikit/text_display_and_fonts/adding_a_custom_font_to_your_app?language=objc

TODO:
think about font weight. Refference from ReactNative: https://github.com/facebook/react-native/blob/master/React/Views/RCTFont.mm

Support for other platforms

Have there been any discussions around supporting platforms other than Android and iOS? It'd be nice to have support for, say, macOS.

Platforms list:

  • Android
  • iOS
  • macOS #127
  • JVM #151
  • JS #272
  • Windows
  • Linux
  • watchOS
  • tvOS
  • androidNative
  • WebAssembly

Add colors support

For use light/dark theme feature colors should be defined in resources, so needed: commonMain/resources/MR/colors.xml with:

<colors>
    <color name="white" themed=true>
        <light>0xFFFFFFFF</light>
        <dark>0x000000FF</dark>
    </color>
    <color name="textColor">0xFF00FFFF</color>
</colors>

Object 'MR' has several compatible declarations in modules MyLib_iosArm64, MyLib_iosX64Main

I'm using the latest version of the lib "0.9.1".

My build gradle is as follows:

kotlin {
    iosX64() {
        binaries.framework {
            baseName = "MyLib"
            isStatic = false
        }
    }
    iosArm64() {
        binaries.framework {
            baseName = "MyLib"
            isStatic = false
        }
    }
    sourceSets {
        ...
        val iosX64Main by getting
        val iosX64Test by getting
        val iosArm64Main by getting {
            dependsOn(iosX64Main)
        }
        val iosArm64Test by getting {
            dependsOn(iosX64Test)
        }

        configure(
            listOf(
                iosArm64Main,
                iosX64Main
            )
        ) {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-properties-native:$serialization_version")
                implementation("io.ktor:ktor-client-ios:$ktor_version")
                implementation("io.ktor:ktor-client-core-native:$ktor_version")
                implementation("io.ktor:ktor-client-serialization-native:$ktor_version")
            }
        }
    }
}

After that I updated to (the target def remains the same, only renamed the folder to iosMain from iosX64Main):

val iosMain by creating {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-properties-native:$serialization_version")
                implementation("io.ktor:ktor-client-ios:$ktor_version")
                implementation("io.ktor:ktor-client-core-native:$ktor_version")
                implementation("io.ktor:ktor-client-serialization-native:$ktor_version")
            }
        }

        val iosX64Main by getting {
            dependsOn(iosMain)
        }

        val iosArm64Main by getting {
            dependsOn(iosMain)
        }
        val iosX64Test by getting
        val iosArm64Test by getting

And now when building I'm getting:
Expected object 'MR' has no actual declaration in module <MyLib_test> for Native

Add integration tests

We have in commonMain/resources set of strings and plurals and changes of library can broke some functional like formatting or usage of special symbols.
Need implement test, which automatically build sample app and check that strings in textview is exactly what should be by test data. And check it on different languages of device.

Support localization change in runtime

  • Add locale property in StringDesc companion
  • Support System / Custom(locale: String) values, implement behavior in actual classes
  • Generate additional iOS localization tables (*.strings files) for custom locales

Duplicated actual MR class when used hierarchically source sets

if we configure project like this:

iosX64()   // for iOS Simulator
    iosArm64() // for iOS arm64 devices
    sourceSets {
        iosMain {
            dependencies {
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-properties-native:$serialization_version"
                implementation "io.ktor:ktor-client-ios:$ktor_version"
                implementation "io.ktor:ktor-client-core-native:$ktor_version"
                implementation "io.ktor:ktor-client-serialization-native:$ktor_version"
            }
        }
        configure([targets.iosX64, targets.iosArm64]) {
            compilations.main {
                source(sourceSets.iosMain)
            }
        }
    }

we have sourceSets:

  • iosX64Main
  • iosArm64Main
  • iosMain

and plugin generate sources for all. but targets use multiple sourceSets in same time:

  • to build iosX64 we use iosX64Main + iosMain
  • to build iosArm64 we use iosArm64Main + iosMain

it's reason why we got Object 'MR' has several compatible actual declarations in modules...

Document the export necessary to work on iOS in the readme

In Issue #53 we learn that there is an extra export statement that is necessary to get this to work on iOS. After losing an entire day trying to figure out why this was not working on iOS, I think it should definitely be documented in the README

iosTest fails with Null pointer exception loading bundle

Maybe related to #48 #80 or #97, but translations are working when running the app, but when I try to run iosTest task I get a null pointer exception in this code:

actual object MR {
  private val bundle: NSBundle by lazy {
      NSBundle.loadableBundle("com.genesys.purecloud.wfmshared.MR") }

Presumably because the resource bundle cannot be found.

I cannot make any headway on trying to track this down

Missed camelCase in R class

When I add some resources in multiplatform resources with camel case key, e.g. testTest, when, after that, I try to access it from R class or from XML I find string testtest. So the question is why is camelCase is missing after generation and how can I fix that behavior?

Add extension methods for additional StringResource types

You have desc extension methods for easily creating StringResource.Raw, StringResource.Resource, and StringDesc.PluralsResource, but there is none for ResourceFormatted or PluralsResourceFormatted. Would be nice to have a simple way to do composition as well with a separator via extension method.

So I am envisioning methods like this:

    myStringResource.format(a, b)

    myPluralsStringResource.format(count, a, b)

   separatorStringDesc.join(stringDesc1, stringDesc2)

   myStringDescList.join(additionalStringDesc, additionalStringDesc, separator = separatorDesc)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.