From 5074bb027c5417b276352a5f82708349d26606e0 Mon Sep 17 00:00:00 2001 From: Luka Date: Fri, 30 Aug 2019 16:25:58 +0200 Subject: [PATCH] Add launch extension on ViewModel class Now we can just call launch{} to launch new coroutine inside the viewModelScope with IO dispatcher as default --- .../common/extensions/AndroidExtensions.kt | 15 ++++++++++++--- .../ui/weather/presentation/WeatherViewModel.kt | 14 +++++--------- .../example/data/database/model/WeatherEntity.kt | 2 +- .../data/networking/model/WeatherInfoResponse.kt | 4 ++-- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/cobeisfresh/template/common/extensions/AndroidExtensions.kt b/app/src/main/java/com/cobeisfresh/template/common/extensions/AndroidExtensions.kt index 14fb62c..8e38f89 100644 --- a/app/src/main/java/com/cobeisfresh/template/common/extensions/AndroidExtensions.kt +++ b/app/src/main/java/com/cobeisfresh/template/common/extensions/AndroidExtensions.kt @@ -7,10 +7,13 @@ import androidx.annotation.IdRes import androidx.annotation.StringRes import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer +import androidx.lifecycle.* +import com.cobeisfresh.template.common.coroutine.CoroutineContextProvider import com.google.android.material.snackbar.Snackbar +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlin.coroutines.CoroutineContext inline fun LiveData.subscribe(owner: LifecycleOwner, crossinline onDataReceived: (T) -> Unit) = observe(owner, Observer { onDataReceived(it) }) @@ -48,4 +51,10 @@ fun FragmentActivity.showFragment(fragment: Fragment, @IdRes container: Int, add fun FragmentActivity.goBack() { supportFragmentManager.popBackStack() +} + +inline fun ViewModel.launch( + coroutineContext: CoroutineContext = CoroutineContextProvider().io, + crossinline block: suspend CoroutineScope.() -> Unit): Job { + return viewModelScope.launch(coroutineContext) { block() } } \ No newline at end of file diff --git a/app/src/main/java/com/cobeisfresh/template/ui/weather/presentation/WeatherViewModel.kt b/app/src/main/java/com/cobeisfresh/template/ui/weather/presentation/WeatherViewModel.kt index 8b04c69..a5dd61d 100644 --- a/app/src/main/java/com/cobeisfresh/template/ui/weather/presentation/WeatherViewModel.kt +++ b/app/src/main/java/com/cobeisfresh/template/ui/weather/presentation/WeatherViewModel.kt @@ -3,19 +3,15 @@ package com.cobeisfresh.template.ui.weather.presentation import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope import com.cobeisfresh.template.common.DEFAULT_CITY_NAME -import com.cobeisfresh.template.common.coroutine.CoroutineContextProvider +import com.cobeisfresh.template.common.extensions.launch import com.cobeisfresh.template.ui.base.ViewState import com.example.domain.interaction.weather.GetWeatherUseCase import com.example.domain.model.WeatherInfo import com.example.domain.model.onFailure import com.example.domain.model.onSuccess -import kotlinx.coroutines.launch -import org.koin.core.KoinComponent -class WeatherViewModel(private val getWeather: GetWeatherUseCase, - private val coroutineContextProvider: CoroutineContextProvider) : ViewModel() { +class WeatherViewModel(private val getWeather: GetWeatherUseCase) : ViewModel() { // we make this private and provide only immutable live data to observers so they can't change anything private val _weatherLiveData = MutableLiveData>() @@ -23,10 +19,10 @@ class WeatherViewModel(private val getWeather: GetWeatherUseCase, get() = _weatherLiveData fun getWeatherForLocation(location: String = DEFAULT_CITY_NAME) = - viewModelScope.launch(coroutineContextProvider.main) { + launch { _weatherLiveData.value = ViewState.loading() getWeather(location) - .onSuccess { _weatherLiveData.value = ViewState.success(it) } - .onFailure { _weatherLiveData.value = ViewState.error(it.throwable) } + .onSuccess { _weatherLiveData.postValue(ViewState.success(it)) } + .onFailure { _weatherLiveData.postValue(ViewState.error(it.throwable)) } } } diff --git a/data/src/main/java/com/example/data/database/model/WeatherEntity.kt b/data/src/main/java/com/example/data/database/model/WeatherEntity.kt index 4c80cdc..668329f 100644 --- a/data/src/main/java/com/example/data/database/model/WeatherEntity.kt +++ b/data/src/main/java/com/example/data/database/model/WeatherEntity.kt @@ -11,7 +11,7 @@ import com.example.domain.model.WeatherInfo @Entity(tableName = WEATHER_TABLE_NAME) data class WeatherEntity(@PrimaryKey val id: Int? = 0, - val weather: ArrayList?, + val weather: List?, @Embedded val main: MainInfo?, val name: String? = "") : DomainMapper { diff --git a/data/src/main/java/com/example/data/networking/model/WeatherInfoResponse.kt b/data/src/main/java/com/example/data/networking/model/WeatherInfoResponse.kt index 96dee9e..c7b699b 100644 --- a/data/src/main/java/com/example/data/networking/model/WeatherInfoResponse.kt +++ b/data/src/main/java/com/example/data/networking/model/WeatherInfoResponse.kt @@ -4,10 +4,10 @@ import com.example.data.database.model.WeatherEntity import com.example.data.networking.base.RoomMapper data class WeatherInfoResponse(val id: Int? = 0, - val weather: ArrayList?, + val weather: List?, val main: MainInfo?, val name: String? = "") : RoomMapper { - override fun mapToRoomEntity() = WeatherEntity(id ?: 0, weather ?: arrayListOf(), main ?: MainInfo(), name) + override fun mapToRoomEntity() = WeatherEntity(id ?: 0, weather ?: emptyList(), main ?: MainInfo(), name) } data class MainInfo(val temp: Double? = 0.0,