Process Retrofit Callback с использованием Moshi для декодирования JSON - PullRequest
0 голосов
/ 26 апреля 2019

Я настраиваю сетевой уровень для приложения, использующего Retrofit + Moshi, который будет иметь ~ 40 сетевых запросов, каждый из которых возвращает данные JSON в согласованном формате.В связи с этим я хотел бы повторно использовать код, который обрабатывает onFailure и onResponse из Callback<T>.

. Например, серверная часть может вернуть следующее:

Success:

{
    "result" {
        "count": 0
    },
    "error": null
}

Ошибка:

{
    "result" null,
    "error": {
        "message": "Some user-friendly error message here."
    }
}

Обратите внимание, что содержимое "result" будет отличаться для каждого успешного запроса, а код состояния равен 200 для сценариев успеха и ошибки.

В настоящее время у меня есть один запрос, который я десериализую в следующие классы:

@JsonClass(generateAdapter = true)
data class SampleWrapper(
    val error: APIError?,
    val result: Sample?
)

@JsonClass(generateAdapter = true)
data class Sample(
    val count: Int
)

Я делаю запрос и обрабатываю его следующим образом:

fun requestSample(context: Context, callback: (Sample?, String?) -> Unit) {
    service.sample.enqueue(object : Callback<SampleWrapper> {
        //TODO: Use a generic function to handle these and pass back Sample? and String?
        override fun onFailure(call: Call<SampleWrapper>, t: Throwable) {
            callback(null, t.message?: context.getString(R.string.unexpected_error_message))
        }

        override fun onResponse(call: Call<SampleWrapper>, response: Response<SampleWrapper>) {
            if (response.isSuccessful && response.body() != null && response.body()?.error == null) {
                callback(response.body()!!.result, null)
            } else {
                callback(null, response.body()?.error?.message?: context.getString(R.string.unexpected_format_error_message))
            }
        }
    })
}

и вызываю эту функциюв действии:

Networking.requestSample(this) { sample, errorMessage ->
    //work with sample or handle error
}

Теперь я хотел бы повторно использовать обработку ответов, поскольку она будет точно такой же для всех запросов, кроме типа объекта, переданного в обратном вызове.Кажется, мне нужно обработать Callback<T>, где T содержит значения error и result, но, возможно, мне нужно сделать этот объект-обертку универсальным.Я изо всех сил пытаюсь выяснить, как этого можно достичь.По сути, я хочу упростить функцию, чтобы она была краткой для каждого запроса, который мы должны определить, и чтобы мы не повторяли повторяющийся код 40x, что-то вроде:

fun requestSample(context: Context, callback: (Sample?, String?) -> Unit) {
    service.sample.enqueue(handler(context, callback))
}
...