This is honestly the only way I was able to do this. Please if you see any mistake or if there is any way you think I can improve on this, I’m all ears. The only issue with this solution is that I am not exactly sure what the web request is returning because I specified a lateint var property named “photos” in the custom deserialization file to be a able to reference it from FlickeFetchr and when I change it to photo, the app crashes saying it hasn’t been initialized (as if no request was returned??). So I got all confused and tired from the researching and this is what I was able to come out with.
import com.bignerdranch.android.photogallery.api.PhotoResponse
import com.google.gson.Gson
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import java.lang.reflect.Type
// OUR CUSTOM JSON DESERIALIZER FILE
class PhotoDeserializer: JsonDeserializer {
lateinit var photos : PhotoResponse // the property
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): PhotoResponse {
val photoJsonObject = json?.asJsonObject
val gson = Gson()
return gson.fromJson(photoJsonObject, PhotoResponse::class.java)
}
}
Our custom converter factory
init {
val gsonPhotoDeserializer = GsonBuilder() // Our Gson instance
.registerTypeAdapter(PhotoResponse::class.java, PhotoDeserializer())
.create()
// custom converter factory
val customGsonConverterFactory = GsonConverterFactory.create(gsonPhotoDeserializer)
val retrofit : Retrofit = Retrofit.Builder()
.baseUrl("https://api.flickr.com/") // the baseUrl is our request endpoint
.addConverterFactory(customGsonConverterFactory)
.build()
flickrApi = retrofit.create(FlickrApi::class.java)
}
fun fetchPhotos(): LiveData<List> {
val responseLiveData: MutableLiveData<List> = MutableLiveData()
val flickrRequest: Call = flickrApi.fetchPhotos()
flickrRequest.enqueue(object: Callback<PhotoDeserializer> {
override fun onFailure(call: Call<PhotoDeserializer>, t: Throwable) {
Log.e(TAG, "Failed to fetch photos", t)
}
override fun onResponse(
call: Call<PhotoDeserializer>,
response: Response<PhotoDeserializer>
) {
// This whole block of code digs the galleryItem list out of the response and updates the live data object with the list(photos).
Log.d(TAG,"Response received $response")
val flickrResponse: PhotoDeserializer? = response.body()
val photoResponse: PhotoResponse? = flickrResponse?.photos // Where I had to reference photos
var galleryItems: List<GalleryItem> = photoResponse?.galleryItems
?: mutableListOf()
galleryItems = galleryItems.filterNot {
it.url.isBlank()
}
responseLiveData.value = galleryItems
}
})
return responseLiveData
}