Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import swift class in kotlin native SharedCode iosMain module

I am using kotlin native and I have successfully integrated it in my project by using build.gradle.kts script from below link

https://play.kotlinlang.org/hands-on/Targeting%20iOS%20and%20Android%20with%20Kotlin%20Multiplatform/03_CreatingSharedCode

By using this I can call my kotlin class into ios app. But I am required to do reverse. I want to call swift classes written in ios app into my kotlin native ios module.

"A Swift library can be used in Kotlin code if its API is exported to Objective-C with @objc. Pure Swift modules are not yet supported." that I have came to know from below link.

https://kotlinlang.org/docs/reference/native/objc_interop.html

For this purpose I believe cinterops {} should be used in build.gradle.kts file by passing header files created from swift class but don't know how to pass it.

like image 724
Kevan Avatar asked Mar 31 '26 03:03

Kevan


1 Answers

Depending on your use case, you can still call the Swift code from Kotlin/Native via a factory function.

My use case was that I needed to instantiate a custom UIView from the Kotlin code. I couldn't find a way to create a fully functional custom UIView in Kotlin directly, unfortunately. I got pretty far with this answer: https://stackoverflow.com/a/69281270 , but hit a limit when I needed to overload updateConstraints() - which has to call super.updateConstraints() and I found no way how to do that via the Kotlin <-> Swift interop (and now I'm reasonably sure it's really not possible).

So instead, I have created the custom UIView in Swift:

class CustomView : UIView {

    ... init etc. ...

    override func updateConstraints() {
        ... my stuff ...
        super.updateConstraints()
    }
}

And implemented a factory function to instantiate it:

func customViewFactory(param: Param) -> UIView {
    return CustomView(param: param)
}

Then early during the app startup, I pass this factory function to the Kotlin/Native code like this:

KotlinClass.Companion.shared.setCustomViewFactory(factory: customViewFactory(param:))

In the Kotlin part of the project (that is actually compiled before the Swift part), it looks like this:

class KotlinClass {

    companion object {
        /* To be used where I want to instantiate the custom UIView from the Kotlin code. */
        lateinit var customViewFactory: (param: Param) -> UIView

        /* To be used early during the startup of the app from the Swift code. */
        fun setCustomViewFactory(factory: (param: Param) -> UIView) {
            customViewFactory = factory
        }
    }

When I want to instantiate the custom UIView in the Kotlin code, I just call:

val customView = customViewFactory(param)

And then can work with it as I need in the Kotlin part - add it to other view or anything...

like image 59
Jan Holesovsky Avatar answered Apr 02 '26 21:04

Jan Holesovsky



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!