What is the best way to create a companion Swift P...
# multiplatform
y
What is the best way to create a companion Swift Package for a KMP library. (details in thread)
swift 1
I have a KMP library that is intended to be used by Kotlin code but want to also provide a Swift Package that will provide integration with Swift only classes (e.g. Swift UI extensions). Ideally, what I would like is to declare a Swift Package that depends on the KMP package. and then ship both to their respective repositories and app includes both (or just KMP if that is all they want). There are 2 ways to make that Swift package depend on the KMP library. 1) I can build a XCF from the KMP Library and depend on it as a binary (declare the XCF as a Swift Package w/ a binary), 2) or I can declare another Swift Package that just includes the generated headers and depend on it. Assuming an APP will add both the KMP library dependency to their shared code and the SPM dependency on their XCode project: If I go w/ 1, i’m simply duplicating all the code in the app (as it will include the KMP library XCF + the code created by their shared module). That might also fail if Kotlin versions skew. (not fully sure on impacts of this) If I go w/ 2, it fails because I have no idea what the generated header prefix will be for the app. I checked KMM-ViewModels which (as far I understand) declares protocols in a Swift Package, imports them to KMP (via cintrop) and implements them in the KMP library (and Swift Package just depends on the protocols). Is that the only way? Is there a more automated + safer way to achieve this w/o manually declaring protocols for all functionality that might be accessed by the SPM?
k
If I understand what option 1 is, let's say I wanted to include your lib in my KMP project. I'd add your KMP dependency to my project, and make a framework from that. I add that to Xcode. Then I'd add your Swift package to Xcode, which depends on the XCF that you created independently and published? That wouldn't work. Kotlin-built frameworks are incompatible with each other at a binary level. So, the Swift would be talking to your XCF exclusively. Trying to pass that into the framework I made, even though it includes the same underlying KMP dependency, would fail because they're not the "same" to Swift (or the Xcode tools, linker, whatever). This is a common problem. You don't know the package name for Swift to import, and you also don't know the names of the classes from Kotlin. Imagine if I had your KMP dep in my project, but it wasn't in the top module. If I didn't explicitly export it, the Kotlin compiler would add a prefix to the name. Also, if for some reason there was a name in your library and something else had the same name in the Kotlin, one of them would get an underscore appended (or prepended, I forget which). You can override that with an annotation, but not if the clashing names are both from dependencies. Not super likely, but still. Not great. The KMM-ViewModels option is fairly clever, but also a lot of "stuff" to accomplish something that seems relatively simple. I believe https://github.com/rickclephas/KMP-NativeCoroutines (same author, Rick) does something else clever that doesn't actually require the import names, but that's 2nd-hand info, and I assume there are pretty painful restrictions. We have a currently undocumented feature of SKIE that lets you put Swift files into your framework. There was a phase there it included a template engine to allow you to specify Kotlin names, which would be replaced by Swift names at compile time. I don't know if the template part still exists. In any case, that would require whoever is using your library to use SKIE to process the framework. Post KC, we'll be discussing if there's a way to use that in sort of a "SKIE-light" mode, or just have a separate tool. SKIE steps into the compiler so it knows the name mappings, etc.
y
i see. yea i was scared of option 1 for the same reasons. Like, there should be an straightforward way to add swift code to a KMP library but this packaging makes is very hard. Thanks for the info, maybe i’ll have some time in the future to dive into this to see if there is any option. As for SKIE, i think it is quite fundemental at this point so requiring clients to use might be an acceptable solution.