Search code examples
androidkotlinretrofit2

How to parse response with retrofit2 Kotlin


I'm stuck with parsing the response. In Swift I can make a codable to help parsing the json response. I'm new to Kotlin and I'm working on someone else existing project. I made a data class for string and boolean but I don't know the syntax to parse it. Please help and thank you.

The responseBody json

{
    "bearerToken": "########",
    "staySignIn": false
} 



    //Interface
    interface PostInterface {
    class User(
        val email: String,
        val password: String
    )

    @POST("signIn")
    fun signIn(@Body user: User): Call<ResponseBody>

    //Network handler
    fun signIn(email: String, password: String): MutableLiveData<Resource> {
            val status: MutableLiveData<Resource> = MutableLiveData()
            status.value = Resource.loading(null)
    
            val retrofit = ServiceBuilder.buildService(PostInterface::class.java)
            retrofit.signIn(PostInterface.User(email, password)).enqueue(object : Callback<ResponseBody> {
                override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                    errorMessage(status)
                }
                override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                    if (response.code() == 200) {
                        try {
                            status.value = //how to parse using the model??
    
                        } catch (ex: Exception) {
                            parseError(400, response.body().toString(), status)
                        }
                    } else {
                        //do something...
                    }
                }
            })
            return status
        }

    //Model
    data class SignInModel(
    
        @field:SerializedName("bearerToken")
        val bearerToken: String? = null,
    
        @field:SerializedName("staySignIn")
        val staySignIn: Boolean? = null
    )

    //Storing value class
    class RrefManager constructor(var applicationContext: Context) {
       private fun getSharedPrefEditor(): sharedPrefEditor.Editor {
         return applicationContext.getSharedPrefEditor(prefStorageName, Context.MODE_PRIVATE).edit()
       }

       public fun setBearerToken(token: String) {
          getSharedPrefEditor().putString("bearerToken", token).apply()
       }

       public fun setStaySignIn(enabled: Boolean) {
          getSharedPrefEditor().putBoolean("staySignIn", enabled).apply()
       }
    }

    //SignIn Button
    viewModel.signIn().observe(viewLifecycleOwner, androidx.lifecycle.Observer { v ->
       if (v.status == Resource.Status.SUCCESS) {   
       val model = v.data as SignInModel
           pref.setToken(model.token as String) //storing value
           pref.setTwoFactorEnabled(model.twoFactorEnabled as Boolean) //storing value
        } else if (v.status == Resource.Status.ERROR) {
          //do something...
        }
    })

Solution

  • I think your best option to achieve something like the codable in swift is to use Gson library for parsing api responses.

    When you create the retrofit instance you pass the gson converter to the builder like:

    val retrofit = Retrofit.Builder()  
                .baseUrl(BaseUrl)  
                .addConverterFactory(GsonConverterFactory.create())  
                .build() 
    

    After you have done that you can make the api return the response you have as the data class, like:

    //Interface
    interface PostInterface {
    
         @POST("signIn")
         fun signIn(@Body user: User): Call<SignInModel>
    }
    

    To read the answer from the callback on your class, the response inside the network call is already parsed into your model in the callback. All the retrofit callback should be changed to receive Callback and then you can access directly like status.value = response.body()

    For more info you can consult the retrofit library page where it gives all the details and explanations on how to use it correctly.

    https://square.github.io/retrofit/