Search code examples
kotlinkotlin-multiplatformktorktor-client

How to download file from an api which returns streamable pdf file in KMM


I have a Kotlin Multiplatform Mobile library which is used in Android and iOS project and Ktor-client framework is being used. I have an api which returns a streamable pdf file. I want to write an api call which should return platform supported format. From mobile platform I should be able to call this api in KMM library and save file into mobile device with the same file name which is given in the api response header. Here is the response header:

connection: keep-alive 
 content-disposition: attachment; filename="bill_123.pdf" 
 content-length: 13161 
 content-security-policy: default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests 
 content-type: application/pdf 

When I try this in Postman I get the file itself.

Since I am new to KMM, need help calling this kind of api.


Solution

  • If the PDF files' sizes fit into the memory, you can read the response body to a ByteArray. To get the original filename, use the ContentDisposition.parse method:

    val client = HttpClient {}
    
    val response = client.get("http://localhost:8080/pdf")
    val disposition = ContentDisposition.parse(response.headers[HttpHeaders.ContentDisposition] ?: "")
    val filename = disposition.parameter("filename")
    val bytes = response.body<ByteArray>()
    

    Also, you can get the body as ByteReadChannel to read the file in chunks:

    val channel = client.get("http://localhost:8080/pdf").bodyAsChannel()