Hello everyone, I am trying to embed Swift xcFrame...
# multiplatform
a
Hello everyone, I am trying to embed Swift xcFramework into a shared KMP library. I have created a wrapper with Obj-C compatible API and proper public header file, made an cinterop to bridge the API to Kotlin. So the shared module compiles nicely. But when I try to launch the iOS app it fails with
Copy code
> Task :shared:linkDebugFrameworkIosArm64 FAILED
error: KLIB resolver: Could not find "/Users/developer/Developer/Sources/KMP/shared/src/iosMain/c_interop/module/KMPWrapper.xcframework/ios-arm64_x86_64-simulator" in [/Users/developer/Developer/Sources/KMP, /Users/developer/.konan/klib, /Users/developer/.konan/kotlin-native-prebuilt-macos-aarch64-2.0.0/klib/common, /Users/developer/.konan/kotlin-native-prebuilt-macos-aarch64-2.0.0/klib/platform/ios_arm64]
error: Compilation finished with errors
as I am trying to export KMPWrapper xcFramework as a part of the shared module:
Copy code
targets
        .filterIsInstance<KotlinNativeTarget>()
        .filter { it.konanTarget.family == Family.IOS }
        .forEach {
            val archXCFrameworkPath = when {
                it.targetName.equals("arm64", ignoreCase = true) -> "$projectDir/src/iosMain/c_interop/module/KMPWrapper.xcframework/ios-arm64"
                else -> "$projectDir/src/iosMain/c_interop/module/KMPWrapper.xcframework/ios-arm64_x86_64-simulator"
            }

            it.binaries.framework {
                baseName = "shared"
                isStatic = true
                @OptIn(ExperimentalKotlinGradlePluginApi::class)
                transitiveExport = true
                export(files(archXCFrameworkPath))
            }

            it.compilations.getByName("main") {
                val KMPWrapper by cinterops.creating {
                    // Path to the .def file
                    definitionFile.set(project.file("src/iosMain/c_interop/KMPWrapper.def"))


                    compilerOpts(
                        "-framework",
                        "KMPWrapper",
                        "-F$archXCFrameworkPath",
                        "-fmodules",
                    )
                }
            }

            it.binaries.all {
                linkerOpts(
                    "-framework",
                    "KMPWrapper",
                    "-F$archXCFrameworkPath",
                    "-fmodules"
                )
            }

        }
What am I doing wrong?
b
I was playing around with the similar thing for a couple of weeks and didn’t manage to resolve it. If you won’t get an answer for your specific question you can still maybe fallback to swift-klib gradle plugin from this repo: https://github.com/ttypic/swift-klib-plugin That is what I ended up using for my library here: https://github.com/BVantur/inspektify
👀 1
a
https://github.com/ttypic/swift-klib-plugin/issues/37 Unfortunately this plugin does not support external dependencies yet.
😢 1
s
I was able to manage this topic with help of this repo https://github.com/ln-12/MultiplatformChaChaPoly (swift library was added as pod to the xcode project)
1
a
I was able to solve without any additional plugins. The reference project was Kottie (KMP wrapper around Lottie) https://github.com/ismai117/kottie
👍 1
b
@Sergey Chuvashev How did you manage to provide cinterop binary to the iOS native project? Did those lines did a trick for you?
Copy code
val xcf = XCFramework()
.
.
.
xcf.add(this)
a
I don't think these lines have something to do with interop. As far as I can see we have 2 options: • link .a library - then klib would integrate it automatically • link Framework - then only API bridge will end up inside klib and the actual Framework has to be added explicitly in the xCode app settings
b
I need to implement the first option for my library. So if I understand this correctly, the idea is to build
.a
artefact and include the file directly to the project. And how do you then link it with the project? I guess some gradle command? When I was manually trying to do cinterop I couldn’t find a way to link binary with the project so I retreat back to using that gradle plugin(I am also sure the answer lies in the implementation code of the plugin itself, but didn’t found the time to dig deeper into that source code).
a
I decided to go with the b option and use Frameworks as I need to link more stuff. But the plugin you shared with me earlier
swift-klib-plugin
does what you need under the hood. I think you can check out its sources and check what commands the author performs.
👍 1
495 Views