Retrofit 2.6.0 exception: java.lang.IllegalArgumentException: Unable to create call adapter for kotlinx.coroutines.Deferred
Reading https://github.com/square/retrofit/blob/master/CHANGELOG.md#version-260-2019-06-05 I saw:
New: Support suspend modifier on functions for Kotlin! This allows you to express the asynchrony of HTTP requests in an idiomatic fashion for the language.
@GET("users/{id}") suspend fun user(@Path("id") long id): User
Behind the scenes this behaves as if defined as fun user(...): Call and then invoked with Call.enqueue. You can also return Response for access to the response metadata.
Currently this integration only supports non-null response body types. Follow issue 3075 for nullable type support.
I changed requests so: added suspend
and removed Deferred
:
@FormUrlEncoded
@POST("user/info/")
suspend fun getUserInfo(@Field("token") token: String): UserInfoResponse
override suspend fun getUserInfo(token: String): UserInfoResponse =
service.getUserInfo(token)
Then in interactor (or simply when called the method getUserInfo(token)
) removed await()
:
override suspend fun getUserInfo(token: String): UserInfoResponse =
// api.getUserInfo(token).await() - was before.
api.getUserInfo(token)
Once I encountered a situation when downloading PDF files required removing suspend
in Api class. See How to download PDF file with Retrofit and Kotlin coroutines?.
In my case I was missing the CoroutineCallAdapterFactory
in my Retrofit initialization. Retrofit v2.5.0
Before:
val retrofit = Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.client(httpClient)
.addConverterFactory(MoshiConverterFactory.create())
.build()
After: (working code)
val retrofit = Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.client(httpClient)
.addConverterFactory(MoshiConverterFactory.create())
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.build()