How to access a String inside the body() in the retrofit in Kotlin?

Asked

Viewed 72 times

0

I’m trying to access the json content inside body() through retrofit. I need the "url" in String. What’s missing from my code?

Debugging the code I saw that the response.body() is returning the following result:

Response{protocol=h2, code=200, message=, url=https://api.photos/public/500x500/czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9wcm9kdWN0cy84MTI1OTIvNmE1ZDFhOTgyYjAwYjdjZDU3MjJhYzQ0NzE3YjVhZGMuanBn}

I’m not able to access the url by typing response.body().url.toString()

Interfaceapi:

interface ImageService {

    @GET("500x500/czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9wcm9kdWN0cy84MTI1OTIvNmE1ZDFhOTgyYjAwYjdjZDU3MjJhYzQ0NzE3YjVhZGMuanBn")
    fun image(): Call<String>

}

Model Image:

class Image<T>{
    val response: String = ""
    var protocol: String = ""
    var message: String = ""
    var url: String = ""


}

Retrofit:

class NetworkUtils private constructor(){


    companion object {

        private lateinit var retrofit: Retrofit
        private fun getRetrofitInstance(): Retrofit {
            val httpClient = OkHttpClient.Builder()
            if(!::retrofit.isInitialized){
                retrofit = Retrofit.Builder()
                    .baseUrl(Constants.BASE_URL_IMG)
                    .client(httpClient.build())
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()

            }
            return retrofit
        }

        fun <T> createService(serviceClass: Class<T>): T{
            return getRetrofitInstance().create(serviceClass)
        }

    }
}

Mainactivity:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_fragment)
        setSupportActionBar(findViewById(R.id.toolbar_edit))


        val remote = NetworkUtils.createService(ImageService::class.java)
        val call: Call<String> = remote.image()
        val response = call.enqueue(object : Callback<String> {
            override fun onResponse(call: Call<String>, response: Response<String>) {
                Log.d("ok", response.body().toString())
            }

            override fun onFailure(call: Call<String>, t: Throwable) {
                Log.d("error", t.toString())
            }

        })

    }
}

Dependencias Gradle:

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation "androidx.cardview:cardview:1.0.0"
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
    implementation "org.koin:koin-android:2.2.0"
    implementation "org.koin:koin-android-scope:2.2.0"
    implementation "org.koin:koin-android-viewmodel:2.2.0"
    implementation 'com.squareup.retrofit2:retrofit:2.8.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
    implementation 'com.squareup.picasso:picasso:2.71828'
    apply plugin: 'kotlin-android-extensions'
    implementation 'com.squareup.retrofit2:converter-scalars:2.8.0'


}

I tested the request in Postman and everything is ok, I believe the problem is in my application

2 answers

0

You need to pass the correct type of return from your service interface:

interface

ImageService {
    @GET("500x500/czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9wcm9kdWN0cy84MTI1OTIvNmE1ZDFhOTgyYjAwYjdjZDU3MjJhYzQ0NzE3YjVhZGMuanBn")
    fun image(): Call<Image>
}

Model Image:

class Image {
    val response: String = ""
    var protocol: String = ""
    var message: String = ""
    var url: String = ""
}

0


I solved this and other result access issues using the Coroutines. Easier to use with a few lines of code.

I followed this tutorial here

Replaces the call.enqueue for:

fun callImage() {

        val apiService = NetworkUtils.createServiceImage(ApiService::class.java)

        GlobalScope.launch(Dispatchers.IO) {
            val result = apiService.image().await()
            Log.d("Result url image = ", result.url)

        }

I automatically generated the class using the plugin JSON to Kotlin class:

class Images {
    val response: String = ""
    var protocol: String = ""
    var message: String = ""
    var url: String = ""
}

And changed the interface:

interface ApiService {

    @GET("500x500/czM6Ly9waG90b3MuZW5qb2VpLmNvbS5ici9wcm9kdWN0cy81NjEyNS9mZjU3NTFmMDc3NjYxMzllOTllODA4OTgwMDQ4YWVkYi5qcGc")
    fun image(): Call<Images>
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.