https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
u

Usman Akhmedov

11/13/2023, 2:33 PM
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

Jeff Lockhart

11/13/2023, 2:44 PM
You need to export the module dependency APIs explicitly to the iOS framework.
u

Usman Akhmedov

11/13/2023, 3:05 PM
Unfortunately it’s not working
f

Francis Mariano

11/13/2023, 3:08 PM
I read in somewhere, I do not remember where, but resource is not compatible with multi modules yet.
j

Jeff Lockhart

11/13/2023, 3:40 PM
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

Francis Mariano

11/13/2023, 3:46 PM
Tks for sharing @Jeff Lockhart
👍 2
u

Usman Akhmedov

11/13/2023, 3:48 PM
@Jeff Lockhart did you add this task into gradle in module with additional resources or into „shared“ module?
j

Jeff Lockhart

11/13/2023, 3:51 PM
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

Usman Akhmedov

11/13/2023, 3:57 PM
@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

Jeff Lockhart

11/13/2023, 6:07 PM
Is composeApp your root framework module?
u

Usman Akhmedov

11/13/2023, 6:08 PM
What do you mean „root“? ComposeApp is a module that depends on all another multiplatform modules
j

Jeff Lockhart

11/13/2023, 6:09 PM
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

Usman Akhmedov

11/13/2023, 6:10 PM
I have already tried to change route to resources, but it doesn’t work
j

Jeff Lockhart

11/13/2023, 6:11 PM
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

Usman Akhmedov

11/13/2023, 6:13 PM
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

Jeff Lockhart

11/13/2023, 6:16 PM
Is
core/design/src/commonMain/resources
the only resource directory you need to copy to the framework?
u

Usman Akhmedov

11/13/2023, 6:16 PM
Yes
j

Jeff Lockhart

11/13/2023, 6:17 PM
Have you confirmed if the resources are present in the compiled framework?
In the file system?
u

Usman Akhmedov

11/13/2023, 6:19 PM
I don’t know how to check it
j

Jeff Lockhart

11/13/2023, 6:43 PM
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?