как передать paremeter модели в MutableLiveData в котлин? - PullRequest
0 голосов
/ 06 ноября 2019

Я занимаюсь разработкой новостей и реализовал сопрограммы Kotlin с помощью Koin. Я успешно создал класс модулей, но не могу передать правильный параметр в класс ViewModel, чтобы при успешном получении данных с сервера на нем отображались данные, поступающие с сервера. когда нет данных, выводится сообщение об ошибке

ниже класса моего модуля

const val BASE_URL  = "https://newsapi.org/"

val appModules = module {
    // The Retrofit service using our custom HTTP client instance as a singleton
    single {
        createWebService<SportNewsInterface>(
            okHttpClient = createHttpClient(),
            factory = RxJava2CallAdapterFactory.create(),
            baseUrl = BASE_URL
        )
    }
    // Tells Koin how to create an instance of CatRepository
    factory<NewsRepository> { (NewsRepositoryImpl( sportNewsInterface= get())) }
    // Specific viewModel pattern to tell Koin how to build MainViewModel
    viewModel { MainViewModel(sportNewsInterface = get())  }
}

/* Returns a custom OkHttpClient instance with interceptor. Used for building Retrofit service */
fun createHttpClient(): OkHttpClient {
    val client = OkHttpClient.Builder()
    client.readTimeout(5 * 60, TimeUnit.SECONDS)
    return client.addInterceptor {
        val original = it.request()
        val requestBuilder = original.newBuilder()
        requestBuilder.header("Content-Type", "application/json")
        val request = requestBuilder.method(original.method(), original.body()).build()
        return@addInterceptor it.proceed(request)
    }.build()
}

/* function to build our Retrofit service */
inline fun <reified T> createWebService(
    okHttpClient: OkHttpClient,
    factory: CallAdapter.Factory, baseUrl: String
): T {
    val retrofit = Retrofit.Builder()
        .baseUrl(baseUrl)
        .addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
        .addCallAdapterFactory(CoroutineCallAdapterFactory())
        .addCallAdapterFactory(factory)
        .client(okHttpClient)
        .build()
    return retrofit.create(T::class.java)
}

ниже MainViewModel.kt, где я вызываю сопрограммы Kotlin

class MainViewModel(
    private val sportNewsInterface: SportNewsInterface

) : ViewModel(), CoroutineScope {
    // Coroutine's background job
    private val job = Job()
    // Define default thread for Coroutine as Main and add job
    override val coroutineContext: CoroutineContext = Dispatchers.Main + job

    private val showLoading = MutableLiveData<Boolean>()
    private val sportList = MutableLiveData <List<SportNewsResponse>>()
    val showError = SingleLiveEvent<String>()

    fun loadNews() {
        // Show progressBar during the operation on the MAIN (default) thread
        showLoading.value = true
        // launch the Coroutine
        launch {
            // Switching from MAIN to IO thread for API operation
            // Update our data list with the new one from API
            val result = withContext(Dispatchers.IO) { sportNewsInterface.getNews() }
            // Hide progressBar once the operation is done on the MAIN (default) thread
            showLoading.value = false
            when (result) {


                is UseCaseResult.Success<List<SportNewsResponse> -> sportList.value = result.data
                is UseCaseResult.Error -> showError.value = result.exception.message
                 }
                }
            }



    override fun onCleared() {
        super.onCleared()
        // Clear our job when the linked activity is destroyed to avoid memory leaks
        job.cancel()
    }
}

ниже UseCaseResult. kt

sealed class UseCaseResult<out T : Any> {
    class Success<out T : Any>(val data: T) : UseCaseResult<<List<SportNewsResponse>>>()
    class Error(val exception: Throwable) : UseCaseResult<Nothing>()
}

ниже SportInterface

interface SportNewsInterface {

    @GET("v2/top-headlines?country=us&apiKey=da331087e3f3462bb534b3b0917cbee9")
     suspend fun  getNews(): List<SportNewsResponse>

    @GET("/v2/top-headlines?sources=espn&apiKey=da331087e3f3462bb534b3b0917cbee9")
    fun getEspn(): Deferred<List<SportNewsResponse>>

    @GET("/v2/top-headlines?sources=football-italia&apiKey=da331087e3f3462bb534b3b0917cbee9")
    fun getFootballItalia(): Deferred<List<SportNewsResponse>>

    @GET("/v2/top-headlines?sources=bbc-sport&apiKey=da331087e3f3462bb534b3b0917cbee9")
    fun getBBCSport(): Deferred<List<SportNewsResponse>>


        }

ниже Класс модели

data class SportNewsResponse(
    val articles: List<Article>,
    val status: String,
    val totalResults: Int
)
...