Can i create kmm library project, that declares so...
# multiplatform
g
Can i create kmm library project, that declares some interface in kotlin, create an actual/expect fun getSomeInterface, and for iOS implement this interface in swift?
h
Nope. You have to define an actual interface in your Kotlin code and Kotlin does not offer Swift interop (yet), only objective c.
But you can write the interface in Kotlin and implement it in Swift.
v
Thats exactly what i want. I have the interface in kotlin, i want to implement it in swift. But my kmm library project does not have an xcodeproj file. I don't understand where to put the swift files
v
Into its own POD and add the pod to KMP?
v
What? I have a kmm library project. In commonMain i have some interface IDoSomething In androidMain: I have ADoMainImpl that uses android API and does something. I want to have SDoDomething.swift for iOS. Is this possible?
v
I am only not sure only about using Swift Implementation directly. But it is for sure possible to have iOSDoSomething.kt which will be just Middle man delegating all the calls into your SDoSmething.swift which is written with Obj-C compatible Swift. And that SDoSmething.swift is added into KMP just as a library via cocoapods (or other dependency framework)
You are not putting your raw swift classes into some folder in shared.
Sorry, I am android developer, but we researched that topic before enrolling into KMP. You basically create your own iOS library, and then simply connect it to the cocoapods in in the shared build.gradle withing cocoapods block:
And then you can use it in Kotlin from iosMain
v
Yeah, that would work for this simple case. But not if you have a bunch of interfaces that return a bunch of different interfaces. It's going to be a pain
v
I mean, are you sure you are in correct path? We are in KMP and we want to write in Kotlin as much as we can
v
I have a project that creates a kotlinNativeKit with a bunch of classes and some interfaces. And two other projects: AndroidKit and IOSKit They completely separated. And this works. I'm trying to unite them into single kmm library project that i can use from compose multiplatform ui project. Using them separately was not possible, due to the fact that the app also needed access to NativeKit. And now i see that uniting them is also hard to impossible
g
@Vladimir Vainer can you pls share
v
Share what? The project is a company private closed source project. Can't share that unfortunately.
r
Stopped using Swift in 2019 for these kind of reasons 🙃
g
I am not asking for complete but yes a bridge where writing some interface which implements in both Platform @Vladimir Vainer
v
But Apple seems to stop using ObjC
r
No, I didn't mean to use ObjC (oh god no). I'm just using Kotlin.
K 1
If you want to use your KMP library from Swift, you have 2 options: • Learn about the limitations of the interop and design the darwin/iOS part of your KMP lib by taking these limitations into account, so that when seen from Swift it looks good enough. Nowadays I think there are enough tools to make that possible, from just the basic interop https://kotlinlang.org/docs/native-objc-interop.html to libraries like https://github.com/rickclephas/KMP-NativeCoroutines • Make a Swift wrapper over your KMP lib. Basically, you accept that your KMP lib's API is not great seen from Swift, and hide it yourself in a wrapper lib. This wrapper lib would basically depend on your KMP lib, and users of your lib would depend on the wrapper lib instead of the KMP lib directly. This can all easily be done using cocoapods.
v
All of that is true for both ways
r
Yes, technically, if you want to use a Swift lib in your Kotlin project (something I'm more used to, as my app is in Kotlin), you either need the Swift lib to be ObjC compatible, then it just work, or you need to make an ObjC compatible wrapper over the Swift lib. The proper solution to this way is proper interoperability with Swift, but we're still at a point where a lot of libraries and almost all core APIs are ObjC compatible
v
Slightly different question: Let's say i have a kmp library project that defines some kotlin class, let's say Calculator. And my lib name is baseCalc. Now, i have a swift app, that uses the baseCalc library and all is well. Now let's assume, i create a new kmp library: advancedCalc, the advancedCalc uses baseCalc. And adds another class: BigDecimalCalculator. If i modify my app, and remove from it the dependency on baseCalc, and just add dependency for advancedCalc. Will I still be able to use Calculator? Or only the BigDecimalCalculator? I can't link to both libraries, as this will create two different versions of Calculator and they are not interchangeable.
To clarify: I have a baseLib with a class Foo. Inside a baseLib there is a function playFoo(foo: Foo) I have advLib that links with baseLib which adds: AdvFoo class which extends from Foo. And some function: animateFoo(foo: Foo) In my iOS app, i want to create an instance of Foo and pass it to animateFoo and to playFoo functions.
r
I don't know enough about Cocoapods to have the answer to that. If your app was in Kotlin and used Gradle, it would only depend on if advancedCalc depends on baseCalc using
api
or
implementation
in the Gradle file. Maybe the Cocoapods Gradle plugin also handles the dependencies this way.
j
The most straightforward way to implement a Kotlin interface in Swift would be to implement and inject that implementation yourself in your iOS app's Swift code at runtime. This works ok for an internal library and app, but not great for something someone else is consuming. If you add a Swift wrapper to your Kotlin library, the wrapper could inject the Swift implementation. It really depends on the API, how feasible a solution like this is though.