Hello, can I build Kotlin-native for iOS directly ...
# kotlin-native
g
Hello, can I build Kotlin-native for iOS directly in Swift?
a
No. Kotlin/Native can only be exported as a Swift/ObjC framework, as described here:https://github.com/JetBrains/kotlin-native/blob/master/OBJC_INTEROP.md
k
if you are authoring new code, I believe you'd be much better served doing so in Kotlin. if you have a dependency to pull in, C and Obj-C are currently supported.
g
Are there thoughts to get there? As I understand iOS developers are getting rid of Objective-C nowadays, and still importing Obj-c in their 100% swift app code brings build time and run time performances issues as far as I understand
k
what are you ultimately trying to do, exactly?
g
Share code between mobile teams in Android and iOS
The feedback I got from our iOS devs is that it costs to import Objc code in lots of places in a Swift app
k
ok, but there's no reason to use Obj-c within a Kotlin MPP, unless you have a dependency
outside of the iOS SDK classes which are Obj-C anyway
g
The idea is to build a .Framework for the iOS team, which will be used in a Swift iOS app
c
That you can already do. - Use Kotlin MPP with code in Kotlin. - On the iOS part of the kotlin MPP project you will use ObjectC API that Kotlin can use straight away. - Then you will export a normal iOS framework which you can use normally in swift
k
☝️
g
Yes I know, but the .Framework output is obj-c with special headers for Swift to look swift-ish. That seems to not be enough for the iOS devs in my team, as they say importing Obj-c code everywhere in Swift adds up build time, as the compiler needs to compile once Swift once Obj-c and link them together. Maybe its a weak argument, maybe not so that’s why I was wondering if I could provide them a .Framework / Swift module directly
XCFramework basically (swift binaries)
k
I"m not sure I buy that. the framework is already compiled. every iOS project already has Obj-C dependencies.
s
Your devs are talking about mixing swift and objc in the same project and they are right. However linking to a framework that is already compiled has minimal cost.
1
k
maybe they're right but I would want to see measurements to validate
c
Same goes when you mix Kotlin and Java, the build time is longer
g
The point of the code being already compiled might be a good one indeed. I need to benchmark all that myself 👍
b
The added build time in that context usually comes from a bridging header (also was improved a lot in Swift 4). Since this is its own framework, there's no bridging header here. You do module-type imports like
import YourKNFramework
, so there's no bridging header involved. You're not adding Obj-C to your project really. You're adding Kotlin, which uses the Obj-C runtime to interop with Swift/Obj-C. All of your Swift classes already do this anyway. For example, if you use Swift's JsonDecoder from Foundation, that still uses NSJSONSerialization under the hood and even generates autoreleased obj-c objects during decoding (i.e. even in Swift 5,
autoreleasepool
is still relevant). This is similarly true of many other classes your app relies on from Foundation: a lot of it is still just nice Swift APIs on top of optimized Obj-C code
💯 1
g
Interesting, thank you @basher ! So wait, do you mean there is a kotlin runtime? I thought the generated binary inside the .Framework was pure Obj-C?
b
There is a runtime for kotlin native yep! It's not pure Obj-C. The promise of the K/N project is that it's an "LLVM-based backend for the Kotlin compiler.…." So Kotlin goes in, arm64 (as one example– other arches as well) comes out. In there is a runtime, which will do things like enforce the stricter memory/concurrency model (https://kotlinlang.org/docs/reference/native/concurrency.html). For Obj-C framework outputs, there's an interop layer that uses the Obj-C runtime to make that work (this glosses over a lot, but i believe is mostly accurate)
s
There is a runtime but it doesn't add much to the binary size. You can verify yourself with a simple hello world one function framework. Obj-C uses a message dispatching mechanism under the hood to communicate with objects and call methods on them. It's very small talk influenced. Kotlin/Native has a bridging mechanism that translates these messages into method calls similar to what Swift does when interoperating with Obj-C.
g
I see, thank you both