15

Fighting with a Kotlin Multiplatform project I have ended with the problem of needing to work with NsData on my iOS platform from the sharedModule working with Kotlin Native.

Because of this, I need to transform objectiveC NsData to Kotlin ByteArray and way back. How can I do this?

halfer
  • 19,824
  • 17
  • 99
  • 186
Francisco Durdin Garcia
  • 12,540
  • 9
  • 53
  • 95

1 Answers1

29

NsData to ByteArray

actual typealias ImageBytes = NSData
actual fun ImageBytes.toByteArray(): ByteArray = ByteArray(this@toByteArray.length.toInt()).apply {
    usePinned {
        memcpy(it.addressOf(0), this@toByteArray.bytes, this@toByteArray.length)
    }
}

ByteArray to NsData

actual fun ByteArray.toImageBytes(): ImageBytes? = memScoped {
    val string = NSString.create(string = this@toImageBytes.decodeToString())
    return string.dataUsingEncoding(NSUTF8StringEncoding)
}

ByteArray to NsData different way

actual fun ByteArray.toImageBytes() : ImageBytes = memScoped { 
    NSData.create(bytes = allocArrayOf(this@toImageBytes), 
        length = this@toImageBytes.size.toULong()) 
}
Francisco Durdin Garcia
  • 12,540
  • 9
  • 53
  • 95
  • 3
    Note option with converting to and then from `NSString` may give you a screwed up result because such conversion adds extra bytes to output, that's why its better to use *only* `allocArrayOf` method – schmidt9 Aug 21 '20 at 13:19
  • 6
    For anyone looking at this solution, note that there are imports needed. I posted https://gist.github.com/noahsark769/61cfb7a8b7231e2069a9dab94cf74a62 which has the full compiling code I used here – Noah Gilmore Oct 16 '20 at 19:09
  • 1
    How can I convert KotlinByteArray to nsdata/nsstring on Swift side after I got it from KMM? – stackich Jul 06 '21 at 22:33
  • @stackich I had the same problem – the only way I found was to define a `ByteArray`-to-`NSData` method in Kotlin and call it from Swift. `fun ByteArray.toNSData() = this.usePinned { NSData.create(it.addressOf(0), this.size.convert()) }` – Nolan Amy Nov 03 '21 at 04:55