Я успешно могу использовать API и получить результат json. Я могу увидеть результат успеха в журналах, напечатав ответное тело Retrofit. а также использование Stetho в качестве сетевого перехватчика.
Однако я не могу понять, почему ответ API все еще "нулевой" в методе onResponse()
в хранилище. Я полагаю, я не передаю правильную модель, может быть, JSON будет правильно проанализирован? Кто-нибудь может помочь мне выяснить, в чем здесь проблема?
Ниже приводится json:
{
"photos": {
"page": 1,
"pages": 2864,
"perpage": 100,
"total": "286373",
"photo": [
{
"id": "49570734898",
"owner": "165034061@N07",
"secret": "f3cb2c2590",
"server": "65535",
"farm": 66,
"title": "Hello",
"ispublic": 1,
"isfriend": 0,
"isfamily": 0
}
],
"photo": [
{
"id": "12344",
"owner": "23444@N07",
"secret": "f233edd",
"server": "65535",
"farm": 66,
"title": "Hey",
"ispublic": 1,
"isfriend": 0,
"isfamily": 0
}
]
},
"stat": "ok"
}
Мой класс Pojo:
data class Photos(
@SerializedName("page")
val page: Int,
@SerializedName("pages")
val pages: Int,
@SerializedName("perpage")
val perpage: Int,
@SerializedName("photo")
val photos: List<Photo>,
@SerializedName("total")
val total: String
)
data class Photo(
@SerializedName("farm")
val farm: Int,
@SerializedName("id")
val id: String,
@SerializedName("isfamily")
val isFamily: Int,
@SerializedName("isfriend")
val isFriend: Int,
@SerializedName("ispublic")
val isPublic: Int,
@SerializedName("owner")
val owner: String,
@SerializedName("secret")
val secret: String,
@SerializedName("server")
val server: String,
@SerializedName("title")
val title: String
)
RetrofitClient:
object ApiClient {
private val API_BASE_URL = "https://api.flickr.com/"
private var servicesApiInterface: ServicesApiInterface? = null
fun build(): ServicesApiInterface? {
val builder: Retrofit.Builder = Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
val httpClient: OkHttpClient.Builder = OkHttpClient.Builder()
httpClient.addInterceptor(interceptor()).addNetworkInterceptor(StethoInterceptor())
val retrofit: Retrofit = builder
.client(httpClient.build()).build()
servicesApiInterface = retrofit.create(
ServicesApiInterface::class.java
)
return servicesApiInterface as ServicesApiInterface
}
private fun interceptor(): HttpLoggingInterceptor {
val httpLoggingInterceptor = HttpLoggingInterceptor()
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return httpLoggingInterceptor
}
interface ServicesApiInterface {
@GET("/services/rest/?method=flickr.photos.search")
fun getImageResults(
@Query("api_key") apiKey: String,
@Query("text") text: String,
@Query("format") format: String,
@Query("nojsoncallback") noJsonCallback: Boolean
): Call<PhotoResponse>
}
}
Операция обратного вызова:
interface OperationCallback<T> {
fun onSuccess(data:List<T>?)
fun onError(error:String?)
}
PhotoDataSource:
interface PhotoDataSource {
fun retrievePhotos(callback: OperationCallback<Photo>, searchText: String)
fun cancel()
}
PhotoRepository:
class PhotoRepository : PhotoDataSource {
private var call: Call<PhotoResponse>? = null
private val API_KEY = "eff9XXXXXXXXXXXXX"
val FORMAT = "json"
companion object {
val TAG = PhotoRepository::class.java.simpleName
}
override fun retrievePhotos(callback: OperationCallback<Photo>, searchText: String) {
call = ApiClient.build()
?.getImageResults(
apiKey = API_KEY,
text = searchText,
format = FORMAT,
noJsonCallback = true
)
call?.enqueue(object : Callback<PhotoResponse> {
override fun onFailure(call: Call<PhotoResponse>, t: Throwable) {
callback.onError(t.message)
}
override fun onResponse(
call: Call<PhotoResponse>,
response: Response<PhotoResponse>
) {
response?.body()?.let {
Log.d(TAG, "got api response total pics are :${it.data?.size}")
if (response.isSuccessful && (it.isSuccess())) {
callback.onSuccess(it.data)
} else {
callback.onError(it.msg)
}
}
}
})
}
override fun cancel() {
call?.let {
it.cancel()
}
}
}
PhotoResponse:
data class PhotoResponse(val status: Int?, val msg: String?, val data: List<Photo>?) {
fun isSuccess(): Boolean = (status == 200)
}