Hi, everyone. I try to follow a multi-module archi...
# multiplatform
u
Hi, everyone. I try to follow a multi-module architecture, and I have three multi-platform modules, the first is shared, it depends on the other two. Everything works well on Android, but iOS does not see the resources from the two lower modules. I write without cocoapods, what should I do?
j
You need to export the module dependency APIs explicitly to the iOS framework.
u
Unfortunately it’s not working
f
I read in somewhere, I do not remember where, but resource is not compatible with multi modules yet.
j
Ah, I read your question wrong. Export is necessary for API. Packaging resources is a separate issue. You can write a Gradle task to copy the resources manually. I have an example here, which you should be able to adapt for your other modules.
f
Tks for sharing @Jeff Lockhart
👍 2
u
@Jeff Lockhart did you add this task into gradle in module with additional resources or into „shared“ module?
j
In my case, this code was for a single module. But you should add it to your root module that builds the iOS framework. You can change the path configuration to take an additional module directory into account when configuring the resource directory to copy from.
u
@Jeff Lockhart If it’s not difficult for you, you can see if I’m doing it right, because I can’t make it work: https://github.com/usmonie/word/tree/enable_onios. Required module for import: coreDesign
j
Is composeApp your root framework module?
u
What do you mean „root“? ComposeApp is a module that depends on all another multiplatform modules
j
You'll need to modify the code for
copyNativeResources
to take an optional module as well as the source set name. Then use that module name, if present, to point the
from("src/$sourceSet/resources")
path to the source set within the module. Something like
from("../$moduleName/src/$sourceSet/resources")
.
What do you mean „root“?
The module that depends on the other modules. The module that is building the shared iOS framework.
👍 1
u
I have already tried to change route to resources, but it doesn’t work
j
copyNativeResources
should only be done in the root module that is building the iOS framework. And it will need to copy the resources from all source sets and modules that you need to get the resources from.
u
Yes, composeapp is a root module, and I tried next code there
Copy code
copyNativeResources("commonMain")

fun copyNativeResources(sourceSet: String) {
    if (sourceSet.isEmpty()) throw IllegalStateException("Valid sourceSet required")

    val prefix = "copy${sourceSet.capitalize()}Resources"

    tasks.withType<KotlinNativeLink> {
        val firstIndex = name.indexOfFirst { it.isUpperCase() }
        val taskName = "$prefix${name.substring(firstIndex)}"

        dependsOn(
            tasks.register<Copy>(taskName) {
                from("../core/design/src/$sourceSet/resources")
                when (outputKind) {
                    CompilerOutputKind.FRAMEWORK -> into(outputFile.get())
                    CompilerOutputKind.PROGRAM -> into(destinationDirectory.get())
                    else -> throw IllegalStateException("Unhandled binary outputKind: $outputKind")
                }
            }
        )
    }

    tasks.withType<FatFrameworkTask> {
        if (destinationDir.path.contains("Temp")) return@withType

        val firstIndex = name.indexOfFirst { it.isUpperCase() }
        val taskName = "$prefix${name.substring(firstIndex)}"

        dependsOn(
            tasks.register<Copy>(taskName) {
                from("../core/design/src/$sourceSet/resources")
                into(fatFramework)
            }
        )
    }
}
j
Is
core/design/src/commonMain/resources
the only resource directory you need to copy to the framework?
u
Yes
j
Have you confirmed if the resources are present in the compiled framework?
In the file system?
u
I don’t know how to check it
j
The framework is in the module build folder. It might be a different location, depending on which Gradle task you're using. Which task are you using to build?