icerockdev / moko-resources Goto Github PK
View Code? Open in Web Editor NEWResources access for mobile (android & ios) Kotlin Multiplatform development
Home Page: https://moko.icerock.dev/
License: Apache License 2.0
Resources access for mobile (android & ios) Kotlin Multiplatform development
Home Page: https://moko.icerock.dev/
License: Apache License 2.0
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
}
}
The generated framework having nested MPP modules with resources generates MR files for them but doesn't contain its assets, which throws an exception in iOS.
Need more samples of StringDesc in main use cases:
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)
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 see sources of plugin on CI:
> Task :gradle-plugin:detekt NO-SOURCE
maybe it not work at all on this project. need fix
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.
install block must contain addition to build.gradle.kts
multiplatformResources {
multiplatformResourcesPackage = "com.icerockdev.library"
}
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.
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.
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()
It will be very useful to overload the plus operator for the StringDesc
class and use concatenation this way:
fun concat(strDesc1: StringDesc, strDesc2: StringDesc): StringDesc {
return strDesc1 + strDesc2
}
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.
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.
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
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
Need to change func to get image in IOS extension, because now it don't work on IOS below 13
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:
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?
For string with char &, encoded with &
<string name="sell.selectMethod.choosePortfolioAmount">CHOOSE PORTFOLIO & 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
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?
gradle plugin for MR object generation contains:
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
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)
}
Need to refactor passing of assets file directory from IosMRGenerator
into resources generators (colors and images). Because now generators gets File
by the file name constant ASSETS_DIR_NAME
.
Hi!
i receive error with pod update.
[!] Unable to find a specification for 'MultiPlatformLibraryResources'.
pod 'MultiPlatformLibraryResources', :git => 'https://github.com/icerockdev/moko-resources.git', :tag => 'release/0.6.0'
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!
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
buildSrc usage now changed - https://gradle.org/whats-new/gradle-6/#plugins-build-logic
to implement icerockdev/moko-widgets#72 required addition of Parcelable interface on resources entities
Need improvements for possibility to pass StringDesc
objects into args
list of toString
function of StringDesc.ResourceFormatted
class. At that moment toString
of StringDesc.ResourceFormatted
with StringDesc
does't work.
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?
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
Related to icerockdev/moko-widgets#250.
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>
For cases when we have a lot of images (ex - big pack of National flags) need to get one of them by name
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
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.
locale
property in StringDesc companionSystem
/ Custom(locale: String)
values, implement behavior in actual classesif 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:
and plugin generate sources for all. but targets use multiple sourceSets in same time:
it's reason why we got Object 'MR' has several compatible actual declarations in modules...
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
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
Need to update readme about the fat-framework gradle task that was added in the 0.10.1 release in #75 .
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?
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)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.