I've been using branch of one of the KMP samples I...
# swift-export
j
I've been using branch of one of the KMP samples I have (https://github.com/joreilly/chip-8/tree/swift_export) to try out Swift Export. Am using Kotlin dev version (that has fix for https://youtrack.jetbrains.com/issue/KT-79785 which I had previously encountered in that sample). Shared code is building fine now (am using
embedSwiftExportForXcode
etc) and now at point where seeing some issues with some of the Swift code I'm using.....more in 🧵
This is what I had in the project....probably better way to do some of this anyway but at least right now seeing issues, as probably expected, with use of
KotlinBoolean
and
KotlinByteArray
....should there be cleaner way right now to pass array like this in to Kotlin code?
Copy code
@Published var screenData = [KotlinBoolean](repeating: false, count: 2048)

private let emulator: Emulator
init(emulator: Emulator) {
    self.emulator = emulator
    
    if let data = loadFile() {
        let intArray : [Int8] = data.map { Int8(bitPattern: $0) }
        let kotlinByteArray: KotlinByteArray = KotlinByteArray.init(size: Int32(data.count))
        for (index, element) in intArray.enumerated() {
            kotlinByteArray.set(index: Int32(index), value: element)
        }
        self.emulator.loadRom(romData: kotlinByteArray)

        self.emulator.observeScreenUpdates(success: { screenData in
            self.screenData = screenData
        })            
    }
}
Emulator
is a shared Kotlin class
a
Hello there 🙂 Well, the question is two-fold. 1.
KotlinBoolean
- we are happy to announce, that there is no
KotlinBoolean
anymore 🙂
kotlin.Boolean
is always mapped into
Swift.Bool
, as it is the most swifty way to represent a boolean. 2.
KotlinByteArray
. Problem you are facing is twofold 🙂 a. With swift export we have introduced multimodule support. That means, that every declaration you have exported - will be a part of the module it was originally declared in. That means, that types that belong to kotlin's
stdlib
- will be a part of a new swift module
KotlinStdlib
. So, in order to instantiate
KotlinStdlib.kotlin.ByteArray
you will have to either explicitly
import KotlinStdlib
, and access
ByteArray
by fqn (
kotlin.ByteArray
), or you can ommit the import part and use the module name as a part of fqn (
KotlinStdlib.kotlin.ByteArray
) b. With swift export we added the support for subscripts. Therefor, the old line
kotlinByteArray.set(index: Int32(index), value: element)
will be transformed into
kotlinByteArray[Int32(index)] = element
. You can continue using the old syntax if you prefer, the method
set
is now renamed into
_set
There is also a problem with
observeScreenUpdates
, as you are trying to assign
ImmutableList
into
Swift.List
. To fix that you have to change the signature of
fun observeScreenUpdates(success: (ImmutableList<Boolean>) -> Unit)
into
fun observeScreenUpdates(success: (List<Boolean>) -> Unit)
Here is the patch with the changes I'm talking about 🙂
j
Thanks @Artem Olkov, will try that later
K 1
I couldn't resist trying 😃. So, everything builds fine now but getting following when I run the app. All changes pushed to https://github.com/joreilly/chip-8/tree/swift_export
using version
2.3.0-dev-4627
btw
tried with
4778
as well fwiw and see same behaviour
a
Interesting. I will have to investigate that a little bit, but as a workaround please create some kind of helper:
Copy code
fun createByteArray(size: Int): ByteArray = ByteArray(size)
and usage:
Copy code
let kotlinByteArray: kotlin.ByteArray = createByteArray(size: Int32(data.count))
j
Thanks, that worked....branch updated.
kodee happy 4
g
@Artem Olkov regarding your answer
1.
it means these mappings will have some changes: https://kotlinlang.org/docs/apple-framework.html#kotlin-numbers-and-nsnumber correct?
I guess KotlinLong will also be converted to Swift.Int64, for instance
Copy code
"Unit" -> "Void"
"List" -> "Array"
"MutableList" -> "Array"
"Set" -> "Set"
"MutableSet" -> "Set"
"Map" -> "Dictionary"
"MutableMap" -> "Dictionary"
"Byte" -> "Int8"
"UByte" -> "UInt8"
"Short" -> "Int16"
"UShort" -> "UInt16"
"Int" -> "Int32"
"UInt" -> "UInt32"
"Long" -> "Int64"
"ULong" -> "UInt64"
"Float" -> "Float"
"Double" -> "Double"
"Boolean" -> "Bool"
"String" -> "String"
Shouldn’t a List be converted to Array? Swift.List is from SwiftUI and not from Swift 🤔
Regarding types, I’ve discovered also that:
androidx.compose.ui.graphics.Color
will not be converted to
UIColor
, instead will be converted to
Int64
ex:
Copy code
data class MyType(val startColor: Long, val endColor: Long) {
    val colors: List<Color> = listOf(Color(startColor), Color(endColor))
}
will be converted to:
Copy code
final public class MyType : KotlinBase {

    public var colors: [Never] { get }

    public var endColor: Int64 { get }

    public var startColor: Int64 { get }

    public init(startColor: Int64, endColor: Int64)

    ...
  }
Not sure if that
colors: [Never]
is something we want 😅
a
regarding your answer
1.
it means these mappings will have some changes: https://kotlinlang.org/docs/apple-framework.html#kotlin-numbers-and-nsnumber correct?
Yes, this link is a tutorial for objective-c export. Swift Export is built from ground up(almost completely) and has it's own conversion rules. The best source of those that we currently have - can be found here. But TBH it's quite outdated, we didn't had the time to document everything properly.
guess KotlinLong will also be converted to Swift.Int64, for instance
Yes, that is correct, kotlin.Long will be translated into Swift.Int64.
Shouldn’t a List be converted to Array? Swift.List is from SwiftUI and not from Swift 🤔
I'm not sure I understand the question? I am sure, that we have a green test, that verifies exactly that translation -
kotlin.List
is converted into
Swift.Array
androidx.compose.ui.graphics.Color
will not be converted to
UIColor
, instead will be converted to
Int64
On the attached example only Long is translated as Int64, and that is correct. Color is translated as
Never
, because it is a value class and we do not support them at the moment. This will be improved in the future releases.
g
> I’m not sure I understand the question? > I am sure, that we have a green test, that verifies exactly that translation -
kotlin.List
is converted into
Swift.Array
| In your previous reply you said: > There is also a problem with
observeScreenUpdates
, as you are trying to assign
ImmutableList
into
Swift.List
. Maybe you wanted to say: “…into Swift.Array? Regarding the remaining information, thank you so much 💪
a
Oh, yes, my bad, I ment the other collection type =D You can imagine the amount of misusage of terminology when the FunctionalTypes were developed (as they are called FunctionalType, Lambda, Closure, block) kodee floating
👍 1
😁 2