Tengo una llamada que devuelve el nombre de diferentes objetos, en este caso, cada nombre es el hash de la dirección de su billetera, pero me gustaría tratarlos de manera indiferente porque lo único que importa son los datos que están dentro de ellos, usando un convertidor estándar como Gson No puedo hacer esto, ¿hay alguna forma de hacerlo manualmente?
{ "0x1234": { "success": true, "cache_last_updated": 1642815869695, "total": 500 }, "0x1244445": { "success": true, "cache_last_updated": 1642815869695, "total": 324 }, "0x47851":{ "success": true, "cache_last_updated": 1642815869695, "total": 324 } }Mi repositorio:
class WalletsResumeRepository( private val service: apiService ) { suspend fun getAddressData(listAddress: List<String>): Flow<Result<List<DetailModel>>> = flow { emit(Result.success(service.getWalletResume(listAddress)) }.catch { e -> emit(Result.failure(RuntimeException("Something went wrong ${e.cause}"))) } }mi repositorio siempre cae en el escenario de captura con un NPE, recordando que la respuesta puede tener innumerables direcciones, por lo que infinitos nombres de objetos, ¿cómo puedo tratarlos como genéricos y mapear solo las respuestas como listas? ¿o algo así?
servicio.kt
suspend fun getWalletResume(@Path("address") wallet: String): WalletDetailDTOMonederoDTO
data class WalletDetailDTO( val success: Boolean, @SerializedName("cache_last_updated") val cacheLastUpdated: Long?, val totalSlp: Int? )Según entiendo su pregunta, esto tiene menos que ver con la actualización y más con el análisis JSON. Debido a que la estructura de la carga útil es un poco incómoda, le sugiero que la consuma en dos pasos:
success del content , cache_last_updated y totalid data class DetailModel(val id: String = "", val success: Boolean, val cache_last_updated: Long, val total: Int) interface apiService { @GET("....") fun getWalletResume( listAddress: List<String> ): Call<Map<String, DetailModel>> } El resultado de llamar a apiService.getWalletResume es Map<String, DetailModel> que luego procesa en el paso 2.
Ejemplo
val json = """ { "0x1234": { "success": true, "cache_last_updated": 1642815869695, "total": 500 }, "0x1244445": { "success": true, "cache_last_updated": 1642815869695, "total": 324 }, "0x47851": { "success": true, "cache_last_updated": 1642815869695, "total": 324 } } """.trimIndent() data class DetailModel(val id: String = "", val success: Boolean, val cache_last_updated: Long, val total: Int) fun main() { val gson = Gson() val type: Type = object : TypeToken<Map<String, DetailModel>?>() {}.type // step 1. simulates the retrofit call val mapResult: Map<String, DetailModel> = gson.fromJson(json, type) // step 2 val result = mapResult.map { entry -> entry.value.copy(id = entry.key) } println(result) // [DetailModel(id=0x1234, success=true, cache_last_updated=1642815869695, total=500), DetailModel(id=0x1244445, success=true, cache_last_updated=1642815869695, total=324), DetailModel(id=0x47851, success=true, cache_last_updated=1642815869695, total=324)] }Me parece que solo está buscando un tipo de respuesta de Map<String, WalletDetailDTO> . Luego, simplemente puede mirar los "valores" en el mapa para obtener una lista única de objetos.
Entonces su llamada de servicio parece
@GET("....") suspend fun getWalletDetails(...): Map<String, WalletDetailDTO>Luego, cuando consuma esos datos, sacaría los valores:
val mapOfWalletDetails = apiService.getWalletResume(...) val walletDetailCollection: Collection<WalletDetailDTO> = mapOfWalletDetails.values() Esta walletDetailCollection final parece ser lo que está buscando si solo desea ignorar las claves en el mapa original.