Данные из SpaceX REST API не отображаются

#android #api #retrofit #okhttp #clean-architecture

Вопрос:

Я пытаюсь создать приложение для Android с помощью API SpaceX. Документация API SpaceX такова: https://github.com/r-spacex/SpaceX-API/blob/master/docs/v4/README.md Я также пытаюсь реализовать чистую архитектуру в своем приложении для Android. Я использую эту конечную точку: https://api.spacexdata.com/v4/launches чтобы получить данные о запусках от SpaceX. Тем не менее, я не могу понять, почему в моем приложении нет никаких ошибок, но оно не показывает данные из API. Вот ApiService интерфейс:

 interface PastLaunchApiService {
    @GET("launches")
    fun getPastLaunches(): Call<PastLaunchResponse>
}
 

Вот такой ApiConfig класс:

 class PastLaunchApiConfig {
    companion object {
        fun getApiService(): PastLaunchApiService{
            val loggingInterceptor =
                HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
            val client = OkHttpClient.Builder()
                .addInterceptor(loggingInterceptor)
                .build()
            val retrofit = Retrofit.Builder()
                .baseUrl("https://api.spacexdata.com/v4/")
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build()
            return retrofit.create(PastLaunchApiService::class.java)
        }
    }
}
 

Вот такой DataSource класс:

 class PastLaunchDataSource: IPastLaunchDataSource {

    private val _loadingStatus = MutableLiveData<Boolean>()
    private val loadingStatus: LiveData<Boolean> = _loadingStatus

    private val _connectionStatus = MutableLiveData<Boolean>()
    private val connectionStatus: LiveData<Boolean> = _connectionStatus

    private val _pastLaunchResponse = MutableLiveData<PastLaunchResponse>()
    private val pastLaunchResponse: LiveData<PastLaunchResponse> = _pastLaunchResponse

    override fun fetchFromApi(){
        _connectionStatus.value = true
        _loadingStatus.value = true
        val client = PastLaunchApiConfig.getApiService().getPastLaunches()
        client.enqueue(object : Callback<PastLaunchResponse> {
            override fun onResponse(
                call: Call<PastLaunchResponse>,
                response: Response<PastLaunchResponse>
            ) {
                if (response.isSuccessful){
                    val pastLaunchResponseValue = response.body()
                    _pastLaunchResponse.value = pastLaunchResponseValue
                    _loadingStatus.value = false
                } else {
                    _connectionStatus.value = false
                    _loadingStatus.value = false
                }
            }

            override fun onFailure(call: Call<PastLaunchResponse>, t: Throwable) {
                _connectionStatus.value = false
                _loadingStatus.value = false
            }

        })
    }

    override fun getPastLaunchFromSource(): LiveData<PastLaunchResponse> {
        fetchFromApi()
        return pastLaunchResponse
    }

    override fun getLoadingStatus(): LiveData<Boolean> {
        return loadingStatus
    }

    override fun getConnectionStatus(): LiveData<Boolean> {
        return connectionStatus
    }
}
 

Затем исходный код данных используется в Repository классе:

 class PastLaunchRepository(private val pastLaunchDataSource: IPastLaunchDataSource):
    IPastLaunchRepository {
    override fun getPastLaunches(): LiveData<PastLaunchResponse> {
        return pastLaunchDataSource.getPastLaunchFromSource()
    }

    override fun getLoadingStatus(): LiveData<Boolean> {
        return pastLaunchDataSource.getLoadingStatus()
    }

    override fun getConnectionStatus(): LiveData<Boolean> {
        return pastLaunchDataSource.getConnectionStatus()
    }
}
 

Then the ViewModel is using the Interactor class:

 class PastLaunchInteractor(private val pastLaunchRepository: IPastLaunchRepository): PastLaunchUseCase {
    override fun getPastLaunches(): LiveData<PastLaunchResponse> {
        return pastLaunchRepository.getPastLaunches()
    }

    override fun getLoadingStatus(): LiveData<Boolean> {
        return pastLaunchRepository.getLoadingStatus()
    }

    override fun getConnectionStatus(): LiveData<Boolean> {
        return pastLaunchRepository.getConnectionStatus()
    }
}
 

Here is the viewModel:

 class PastLaunchViewModel(private val pastLaunchUseCase: PastLaunchUseCase):ViewModel() {

    fun getPastLaunches(): LiveData<PastLaunchResponse> = pastLaunchUseCase.getPastLaunches()

    fun getLoadingStatus(): LiveData<Boolean> = pastLaunchUseCase.getLoadingStatus()

    fun getConnectionStatus(): LiveData<Boolean> = pastLaunchUseCase.getConnectionStatus()
}
 

And finally I’m testing whether the connection worked by displaying to a simple textview on the activity:

 viewModel.getPastLaunches().observe(this,{
            val data = it.pastLaunchResponse?.size.toString()
            binding.tvTest.text = data
            println(data)
        })
 

The weird thing is that I got no error and the client is returning a succesful connection. This is my logcat:

 2021-06-16 17:00:42.469 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: <-- 200 ************************************** (1188ms)
2021-06-16 17:00:42.469 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: access-control-allow-origin: *
2021-06-16 17:00:42.469 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: access-control-expose-headers: spacex-api-cache,spacex-api-response-time
2021-06-16 17:00:42.469 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: alt-svc: h3-29=":443"; ma=2592000,h3-34=":443"; ma=2592000,h3-32=":443"; ma=2592000
2021-06-16 17:00:42.469 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: cache-control: max-age=20
2021-06-16 17:00:42.469 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: content-security-policy: default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: content-type: application/json; charset=utf-8
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: date: Wed, 16 Jun 2021 10:00:43 GMT
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: etag: "512bd-t5u 0jrrLE3lf0AU/jfe1wPmE1s"
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: expect-ct: max-age=0
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: referrer-policy: no-referrer
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: server: Caddy
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: spacex-api-cache: MISS
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: spacex-api-cache-online: true
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: spacex-api-response-time: 71ms
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: strict-transport-security: max-age=15552000; includeSubDomains
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: vary: Origin
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: vary: Accept-Encoding
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: x-content-type-options: nosniff
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: x-dns-prefetch-control: off
2021-06-16 17:00:42.470 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: x-download-options: noopen
2021-06-16 17:00:42.471 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: x-frame-options: SAMEORIGIN
2021-06-16 17:00:42.471 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: x-permitted-cross-domain-policies: none
2021-06-16 17:00:42.471 10480-10512/com.briancatraguna.spacex I/okhttp.OkHttpClient: x-xss-protection: 0
2021-06-16 17:00:42.808 10480-10497/com.briancatraguna.spacex W/System: A resource failed to call close. 
2021-06-16 17:00:42.808 10480-10497/com.briancatraguna.spacex W/System: A resource failed to call close.