1
votes

I'm using Retrofit2 for the first time, so I'm confused how to proceed. I have the following code

fun getAddressFromPostCode(postCode: String): List<PXAddress>{

    val trimmedPostCode = postCode.replace("\\s".toRegex(),"").trim()
    val dataBody = JSONObject("""{"postCode":"$trimmedPostCode"}""").toString()
    val hmac = HMAC()
    val hmacResult = hmac.sign(RequestConstants.CSSecretKey, dataBody)
    val body = JSONObject("""{"data":"$dataBody", "data_signature":"$hmacResult"}""").toString()
    val url = RequestConstants.getAddress

    val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl(url)
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    val address: PXAddress = retrofit.create(PXAddress::class.java)
}

with the idea that body needs to look like this:

    "data":{
        "postcode": "WA1 1LD"
    },
    "data_signature": "{{getSignature}}"
}

and the response should be

    "success": 1,
    "addresses": [
        {
            "address1": "47 Museum Street",
            "address2": null,
            "address3": null,
            "town": "WARRINGTON",
            "county": "",
            "postcode": "WA1 1LD"
        },
        {
            "address1": "49a Museum Street",
            "address2": null,
            "address3": null,
            "town": "WARRINGTON",
            "county": "",
            "postcode": "WA1 1LD"
        },
        {
            "address1": "Leda Recruitment",
            "address2": "49 Museum Street",
            "address3": null,
            "town": "WARRINGTON",
            "county": "",
            "postcode": "WA1 1LD"
        }
    ]
}

And I need to convert that response into a list of PXAddress which is

open class PXAddress : RealmObject() {

    var addressLine1: String? = null
    var addressLine2: String? = null
    var addressLine3: String? = null
    var town: String? = null
    var county: String? = null
    var postcode: String? = null
}
1

1 Answers

2
votes

Your implementation is wrong for some reasons:

  1. Use an interface to define the web service request, you must define a class like this:
    interface ApiService {
        @POST("your/webservice/path")
        fun getPXAddress(@Body dataBody: YourBodyModel): Call<List<PXAddress>>
    }
  1. You must call your webservice with a data class as body, the gson converter will convert your models in json, in your main code you must do that:
fun getAddressFromPostCode(postCode: String): List<PXAddress>{
    val trimmedPostCode = postCode.replace("\\s".toRegex(),"").trim()
    val dataBody = DataBodyObject(postCode = trimmedPostCode)

    val hmac = HMAC()
    val hmacResult = hmac.sign(RequestConstants.CSSecretKey, dataBody)

    val yourBodyModel = YourBodyModel(data = dataBody, data_signature = hmacResult)

    val url = RequestConstants.getUrl() // This address must be only the host, the path is specified in ApiService interface

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

    val api: ApiService = retrofit.create(ApiService::class.java) // With this you create a instance of your apiservice

    val myCall: Call<List<PXAddress>> = api.getPXAddress(yourBodyModel) //with this you can call your service synchronous

}
  1. One last thing, you must call your method asynchronous mode with rxjava, livedata or coroutines. All of them offers converters to retrofit. By default, retrofit has a call method like the example that I show you, you can complete your code doing this:
    myCall.enqueue(object : Callback<List<PXAddress>> {
        override fun onFailure(call: Call<List<PXAddress>>?, t: Throwable?) {
            // Error response
        }

        override fun onResponse(call: Call<List<PXAddress>>?, response: Response<List<PXAddress>>?) {
            // Success response
            val myList : List<PXAddress> = response?.body
        }

    })

Best regards!