Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Retrofit methods more expressive way

I want to make void enqueue(Callback<T> callback); method invocation code block more expressive, Here is what I have an usually

request.enqueue(object : Callback<MyModel> {       override fun onFailure(call: Call<MyModel>?, t: Throwable?) {            //       }        override fun onResponse(call: Call<MyModel>?, response: Response<MyModel>?) {            //       }  }) 

And what I want and mean is that, to change this code blocks more cleaner way and remove those override, object, Callback keywords and do something like that:

request.enqueue({throwable, response -> })

I think it could be improved somehow using extensions and higher-order functions. Does anyone know how it can be done?

like image 799
Jemo Mgebrishvili Avatar asked Apr 05 '17 13:04

Jemo Mgebrishvili


People also ask

What is the purpose of a Retrofit interface?

Retrofit is a REST Client for Java and Android allowing to retrieve and upload JSON (or other structured data) via a REST based You can configure which converters are used for the data serialization, example GSON for JSON.

What is Retrofit and its benefits Android?

Retrofit is a type-safe HTTP networking library used for Android and Java. Retrofit was even better since it was super fast, offered better functionality, and even simpler syntax. Most developers since then have switched to using Retrofit to make API requests.

How do you call a Retrofit method?

OBSERVABLE" section on Retrofit's website. This will explain to you the basics on how to declare your APIs for your different needs. The simplest way of getting access to your JSON class object is to map it to a Java object and let Retrofit do the conversion for you.

What is Retrofit in web services?

Retrofit is a type-safe REST client for Android, Java and Kotlin developed by Square. The library provides a powerful framework for authenticating and interacting with APIs and sending network requests with OkHttp.


2 Answers

this is how i do it with extension function and a class

fun<T> Call<T>.enqueue(callback: CallBackKt<T>.() -> Unit) {     val callBackKt = CallBackKt<T>()     callback.invoke(callBackKt)     this.enqueue(callBackKt) }  class CallBackKt<T>: Callback<T> {      var onResponse: ((Response<T>) -> Unit)? = null     var onFailure: ((t: Throwable?) -> Unit)? = null      override fun onFailure(call: Call<T>, t: Throwable) {         onFailure?.invoke(t)     }      override fun onResponse(call: Call<T>, response: Response<T>) {         onResponse?.invoke(response)     }  } 

then you can use it like this

request.enqueue {      onResponse = {         // do     }      onFailure = {         // do     }  } 
like image 193
codegames Avatar answered Sep 21 '22 07:09

codegames


Given the following function:

fun <T> callback(fn: (Throwable?, Response<T>?) -> Unit): Callback<T> {     return object : Callback<T> {         override fun onResponse(call: Call<T>, response: retrofit2.Response<T>) = fn(null, response)         override fun onFailure(call: Call<T>, t: Throwable) = fn(t, null)     } } 

You can use this with Retrofit like this:

request.enqueue(callback({ throwable, response ->  response?.let { callBack.onResponse(response.body() ?: RegisterResponse()) }  throwable?.let { callBack.onFailed(throwable.message!!) }) 

Alternately, you can define this other version of callback:

fun <T> callback2(success: ((Response<T>) -> Unit)?, failure: ((t: Throwable) -> Unit)? = null): Callback<T> {     return object : Callback<T> {         override fun onResponse(call: Call<T>, response: retrofit2.Response<T>) { success?.invoke(response) }         override fun onFailure(call: Call<T>, t: Throwable) { failure?.invoke(t) }     } } 


which can be used like this:

request.enqueue(callback2(                 { r -> callBack.onResponse(r.body()) },                 { t -> callBack.onFailed(t.message) })) 
like image 34
pdpi Avatar answered Sep 18 '22 07:09

pdpi