Search code examples
androidjsonkotlinkotlin-multiplatform

toJson and fromJson cross platform support


I have an android application written in Kotlin. I have a number of classes, and for each class I make use of Gson's toJson and fromJson functions for those classes. For example:

class A{

fun toJson():String {
        return Gson().toJson(this)
    }

fun fromJson(jsonString:String):A{
            return Gson().fromJson(jsonString, A::class)
   }
}

I have another class B:

class B{
    
    fun toJson():String {
            return Gson().toJson(this)
        }
    
    fun fromJson(jsonString:String):B{
                return Gson().fromJson(jsonString, B::class)
       }
    }

The way I used this was creating an instance of the class and then calling the method (note: I am creating an instance of this class (class A) in another class:

val a = A()    
a.toJson()

But I am now trying to convert this into a kotlin multiplatform project but unsure how to go about approaching the to and from json conversions in kotlin multiplatform.

I tried creating expect functions as such:

expect fun toJsonClassA():String
expect fun fromJsonClassA(jsonString: String): A

class A{

}

and then implementing them the actual implementations as such:

actual fun toJsonClassA(): String {
    return Gson().toJson(A::class.java)
}

With the above platform specific implementations, I cannot call the toJsonClassA or the fromJsonClassA functions with the instance of the class name.

This won't work:

val a = A()
a.toJsonClassA()

Any help or advice as to how I can implement the Json serialization and de-serialization in Kotlin Multiplatform will be highly appreciated.


Solution

  • To answer your question. You need a multiplatform json serializer (not GSon coz it for jvm only) and at the moment I know only kotlinx.serialization. And with it, your code should look like this

    @Serializable
    class A {
      fun toJson() = Json.stringify(A.serializer(),this)
      companion object {
        fun fromJson(json: String) = Json.parse(A.serializer(),json)
      }
    }
    

    While that will work, You don't need the toJson and fromJson methods. Since when you have a class like

    @Serializable
    class B {}
    
    val b = B()
    

    all you need with kotlinx.serialization

    • To convert to Json, Json.stringify(B.serializer(),b)
    • To parse Json to kotlin object, Json.parse(B.serializer(),"{}")