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): UserInfoResponseoverride 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)
UPDATE
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()