-1

I've a kmm project. I am trying to upload a video. For small files I can convert Data to ByteArray, but what to do about videos > 30MBs?

For android, I convert File to ByteReadChannel and set as the body setBody(byteReadChannel)

For iOS, I'm not able to convert to a ByteReadChannel.

1 Answer 1

1

You can read from the file asynchronously using the dispatch_read function. The data exposed in the handler can then be written to a ByteWriteChannel using the pointer to the data object's contents. To read the entire file, the dispatch_read method should be called multiple times until the returned data pointer is null. The suspendCancellableCoroutine function is used to transform the dispatch_read function with a callback to a suspend function.

Here is an example of how you can stream a request body read from a file:

private const val BUFFER_SIZE = 4088
// ...

val queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT.convert(), 0u)
val file = "/path/to/file"

val client = HttpClient(Darwin)
val response = client.post("https://httpbin.org/post") {
    setBody(bodyFromFile(file, queue))
}

// ...

@OptIn(ExperimentalForeignApi::class)
private fun bodyFromFile(path: String, queue: dispatch_queue_t): OutgoingContent {
    suspend fun read(fd: Int): NSData? {
        return suspendCancellableCoroutine { continuation ->
            dispatch_read(fd, BUFFER_SIZE.toULong(), queue) { dispatchData, _ ->
                val data = dispatchData as NSData
                continuation.resume(if (data.bytes != null) data else null)
            }
        }
    }

    return ChannelWriterContent(contentType = ContentType.defaultForFilePath(path), body = {
        val fd = open(path, O_RDWR)
        try {
            while (true) {
                val data = read(fd) ?: break
                val bytes: CPointer<ByteVar> = data.bytes!!.reinterpret()
                writeFully(bytes, 0, data.length.toInt())
                flush()
            }
        } finally {
            close(fd)
        }
    })
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.