any help on this issue please? its related to kmm
# multiplatform
d
any help on this issue please? its related to kmm
b
I hit this issue a while back too. I can’t remember exactly how I fixed it, but try this:
Copy code
kotlin {
  listOf(
    iosX64(),
    iosArm64(),
  ).forEach {
    it.binaries.framework {
      baseName = "shared"
      isStatic = true
      linkerOpts("-framework") // I have "Network" added also but might be for something else   
    }
  }
}
My
Build Phases
tab looks similar but I only have
FirebaseMessaging
. I have this for my package dependencies
image.png
d
the problem with static is that will add the packages to the iOS app binaries, hence the app for the end user will be bigger
k
the problem with static is that will add the packages to the iOS app binaries, hence the app for the end user will be bigger
Which packages? Static builds are generally smaller overall, unless there's something I'm not aware of here. In any case, you haven't added Firebase with cocoapods. That is required if you are building a dynamic framework, and/or if you want to run Kotlin tests with iOS targets. https://github.com/GitLiveApp/firebase-kotlin-sdk?tab=readme-ov-file#running-on-ios The Kotlin dependencies only include cinterop for Firebase. They do not link to Firebase binaries. It is a common problem when including 3rd party libraries on native platforms. I gave a talk about these topics a couple years ago. The title on the page hosting the video is incorrect, but the video talks about how cinterop and linking work: https://www.droidcon.com/2022/06/28/sdk-design-and-publishing-for-kotlin-multiplatform-mobile/
The immediate reaction is probably "we're not using Cocoapods". That's OK. The use of Cocoapods in the Kotlin build is only to grab and link the Firebase binary during compilation and testing. It won't be bundled into the assembled framework, and you don't need to use Cocoapods in your Xcode build. There's a flag in that config that essentially says "don't generate cinterop Kotlin bindings", IIRC, which you should set. You're not using Cocoapods to generate Kotlin cinterop wrappers. You're just using it to link to Firebase.
You can do this without Cocoapods, but it will be a lot of manual work and, if you're not pretty familiar with native builds and linking, it'll be pretty confusing. I'm fairly familiar with those topics, and I'd assume setting up manual linking would take considerable time.
d
Thank you for the detailed reply, yes, we do not use Cocoapods.
s
@kpgalligan Do you have any example or insight into this from your message above?
Copy code
and you don't need to use Cocoapods in your Xcode build. There's a flag in that config that essentially says "don't generate cinterop Kotlin bindings"
Based on what I'm seeing, I'm forced to use cocoapods to publish a framework as soon as I add any third party cocoapod dependency in my module. I was trying to add
cocoapods
only for grabbing and linking the binary for compilation and testing and then wanted to publish
XCFramework
for my actual KMP library and was hoping that as long as the
ios app
satisfies the binaries at run time, it would be okay. But that's doesn't seem like the case, or maybe I'm missing something.
k
Based on what I'm seeing, I'm forced to use cocoapods to publish a framework as soon as I add any third party cocoapod dependency in my module.
Where are you seeing that? In theory, the cocoapods link should satisfy the build, and publishing should be separate. Dynamic frameworks will complicate everything considerably. Static should be simpler. It is possible that you'll need a custom
Package.swift
file that includes the dependencies you reference, but that I'm less certain of. The SPM publishing process doesn't run the same checking that CocoaPods does, so if the framework itself builds, you should be able to publish it. If the errors are on the consuming end, that's a different discussion.
s
So here is what I'm trying, • Umbrella Module ◦ Export Module A
api(:a)
• Module A ◦ Add a third party
pod()
Now I was trying to export
umbrella
as XCFramework and locally use it in native iosApp. No SPM use. Just wanted to copy the framework and use it in native app. But I can't seem to generate
XCFramework
at all. There is no
build<Nam>XCFramework
task anymore. I'll share some code tomorrow to explain better
k
build<Nam>XCFramework
tasks only exist if you configure
XCFramework
in Gradle, or use KMMBridge (which configures
XCFramework
itself). https://github.com/touchlab/KMMBridge/blob/main/kmmbridge/src/main/kotlin/co/touchlab/kmmbridge/KMMBridge.kt#L76
How'd it go?
s
I'm working on building a sample project to share here. Either I don't understand the possibilities of exporting with cocoapods in use or there is a legit limitation somewhere.
👍 1
@kpgalligan After creating a new sample, I learned that my main issue yesterday was that my umbrella module was empty with no files and somehow that was causing issues. I had multiple modules with code and then was trying exporting with an umbrella and that was failing. I can export
XCFramework
now. I use cocoapods plugin to include some iOS native dependency. I get warnings like this while building the framework --
can't be exported with -Xexport-library
but at runtime I'm not seeing issues. I have to add cocoapod on Xcode project side, and that's expected because KMP framework would need to link it at runtime.
oh, and
embed framework
option doesn't work with
cocoapods
. So that was another issue I was facing but that's not a big problem. I anyways wants to export
XCFramework
. Kotlin docs also mention here that the direct integration method doesn't work if KMP has cocoapods dependencies https://kotlinlang.org/docs/multiplatform-direct-integration.html
k
I have to add cocoapod on Xcode project side
Is there a reason you're going through the extra trouble for
XCFramework
if you're already using CocoaPods? Seems like a lot of extra effort.
oh, and
embed framework
option doesn't work with
cocoapods
.
The docs say to migrate if you're using CocoaPods for integration. I've found their docs to not always be complete. Unless the embed task checks and fails if it finds the cocoapods plugin, I think you could use cocoapods with link-only and embed together, assuming you're building a static framework, but I'm not 100% sure. but, again, the docs tend to lean towards trying not to confuse devs with more iOS/Xcode details than necessary. It's something I run into periodically. But, in any case, glad it's working.
I learned that my main issue yesterday was that my umbrella module was empty with no files and somehow that was causing issues
I've seen this. It doesn't see code, so it skips building altogether.
c
I'm going through this exact problem too, including PostHog using Cocoapods in a module in our KMP project that then is built as an XCFramework umbrella SDK, but I get linking errors when buildling the umbrella framework. Looking at your talk from Droidcon and what you write above, it seems that this kind of setup is not ideal. But if I want to use analytics internally in the KMP SDK, it will essentially link the PostHog library twice?
or how do I pass to the umbrella SDK that it needs to link with PostHog? I tried adding
Copy code
cocoapods {
        pod("PostHog", linkOnly = true)
    }
in the umbrella module, but I still get
Copy code
The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1.
output:
ld: warning: ignoring duplicate libraries: '-ldl'
ld: framework 'PostHog' not found
I got this work now with the help of @shaktiman_droid I was wrongly building the analytics gradle module as a framework and then the umbrella framework had explicitly
isStatic
set to false.
❤️ 1