diff --git a/build.gradle b/build.gradle index ef852ee..1467a26 100644 --- a/build.gradle +++ b/build.gradle @@ -14,10 +14,9 @@ buildscript { repositories { google() jcenter() - } dependencies { - classpath 'com.android.tools.build:gradle:3.4.2' + classpath 'com.android.tools.build:gradle:3.5.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -28,7 +27,6 @@ allprojects { repositories { google() jcenter() - } } diff --git a/data/src/main/java/com/example/data/di/DatabaseModule.kt b/data/src/main/java/com/example/data/di/DatabaseModule.kt index b3a6396..912f62d 100644 --- a/data/src/main/java/com/example/data/di/DatabaseModule.kt +++ b/data/src/main/java/com/example/data/di/DatabaseModule.kt @@ -6,10 +6,12 @@ import com.example.data.database.WeatherDatabase import org.koin.android.ext.koin.androidContext import org.koin.dsl.module +private const val WEATHER_DB = "weather-database" + val databaseModule = module { single { //TODO remove fallbackToDestructiveMigration when this goes to production - Room.databaseBuilder(androidContext(), WeatherDatabase::class.java, "weather-database").fallbackToDestructiveMigration().build() + Room.databaseBuilder(androidContext(), WeatherDatabase::class.java, WEATHER_DB).fallbackToDestructiveMigration().build() } factory { get().weatherDao() } } \ No newline at end of file diff --git a/data/src/main/java/com/example/data/di/NetworkingModule.kt b/data/src/main/java/com/example/data/di/NetworkingModule.kt index 4e60864..00c8257 100644 --- a/data/src/main/java/com/example/data/di/NetworkingModule.kt +++ b/data/src/main/java/com/example/data/di/NetworkingModule.kt @@ -9,6 +9,7 @@ import org.koin.dsl.module import retrofit2.Converter import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory +import java.util.concurrent.TimeUnit private const val BASE_URL = "http://api.openweathermap.org/data/2.5/" const val API_KEY = "1ca34d622e60278cc8a62d2f53f2c982" @@ -19,6 +20,7 @@ val networkingModule = module { single { OkHttpClient.Builder().apply { if (BuildConfig.DEBUG) addInterceptor(get()) + .callTimeout(10, TimeUnit.SECONDS) }.build() } single { diff --git a/data/src/main/java/com/example/data/di/RepositoryModule.kt b/data/src/main/java/com/example/data/di/RepositoryModule.kt index 652bff0..d3fdd57 100644 --- a/data/src/main/java/com/example/data/di/RepositoryModule.kt +++ b/data/src/main/java/com/example/data/di/RepositoryModule.kt @@ -1,6 +1,7 @@ package com.example.data.di import com.example.data.repository.weather.WeatherRepositoryImpl +import com.example.data.utils.Connectivity import com.example.data.utils.ConnectivityImpl import com.example.domain.repository.WeatherRepository import org.koin.android.ext.koin.androidContext @@ -8,5 +9,5 @@ import org.koin.dsl.module val repositoryModule = module { factory { WeatherRepositoryImpl(get(), get(), get()) } - factory { ConnectivityImpl(androidContext()) } + factory { ConnectivityImpl(androidContext()) } } \ No newline at end of file diff --git a/data/src/main/java/com/example/data/networking/base/NetworkResult.kt b/data/src/main/java/com/example/data/networking/base/NetworkResult.kt index 59dc012..d22c0e7 100644 --- a/data/src/main/java/com/example/data/networking/base/NetworkResult.kt +++ b/data/src/main/java/com/example/data/networking/base/NetworkResult.kt @@ -3,10 +3,7 @@ package com.example.data.networking.base import com.example.domain.model.HttpError import retrofit2.Response -abstract class NetworkResult : DomainMapper - interface DomainMapper { - fun mapToDomainModel(): T } 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 dcf7bb3..96dee9e 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 @@ -7,7 +7,7 @@ data class WeatherInfoResponse(val id: Int? = 0, val weather: ArrayList?, val main: MainInfo?, val name: String? = "") : RoomMapper { - override fun mapToRoomEntity() = WeatherEntity(id ?: 0, weather ?: emptyList(), main ?: MainInfo(), name) + override fun mapToRoomEntity() = WeatherEntity(id ?: 0, weather ?: arrayListOf(), main ?: MainInfo(), name) } data class MainInfo(val temp: Double? = 0.0, diff --git a/data/src/main/java/com/example/data/repository/weather/WeatherRepositoryImpl.kt b/data/src/main/java/com/example/data/repository/weather/WeatherRepositoryImpl.kt index bdf17d4..12cd5ee 100644 --- a/data/src/main/java/com/example/data/repository/weather/WeatherRepositoryImpl.kt +++ b/data/src/main/java/com/example/data/repository/weather/WeatherRepositoryImpl.kt @@ -9,25 +9,32 @@ import com.example.data.networking.base.onSuccess import com.example.data.utils.Connectivity import com.example.domain.model.* import com.example.domain.repository.WeatherRepository +import kotlinx.coroutines.withTimeout +import okio.Timeout +import java.io.IOException class WeatherRepositoryImpl(private val weatherApi: WeatherApi, private val weatherDao: WeatherDao, private val connectivity: Connectivity) : WeatherRepository { override suspend fun getWeatherForLocation(location: String): Result { - if (connectivity.hasNetworkAccess()) { - weatherApi.getWeatherForLocation(location) - .onSuccess { - val weatherInfo = weatherDao.updateWeatherAndReturn(it.mapToRoomEntity()) - return Success(weatherInfo.mapToDomainModel()) - } - .onFailure { return Failure(it) } + try { + if (connectivity.hasNetworkAccess()) { + weatherApi.getWeatherForLocation(location) + .onSuccess { + val weatherInfo = weatherDao.updateWeatherAndReturn(it.mapToRoomEntity()) + return Success(weatherInfo.mapToDomainModel()) + } + .onFailure { return Failure(it) } + return Failure(HttpError(Throwable(GENERAL_NETWORK_ERROR))) + } else { + val weatherInfo = weatherDao.getWeatherInfoForCity(location) + @Suppress("SENSELESS_COMPARISON") // room can return null here even though it's not nullable type + return if (weatherInfo != null) Success(weatherInfo.mapToDomainModel()) + else Failure(HttpError(Throwable(DB_ENTRY_ERROR))) + } + } catch (e: IOException) { return Failure(HttpError(Throwable(GENERAL_NETWORK_ERROR))) - } else { - val weatherInfo = weatherDao.getWeatherInfoForCity(location) - @Suppress("SENSELESS_COMPARISON") // room can return null here even though it's not nullable type - return if (weatherInfo != null) Success(weatherInfo.mapToDomainModel()) - else Failure(HttpError(Throwable(DB_ENTRY_ERROR))) } } } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 7dcda3f..082974b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,44 +1,31 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit +## For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html +# # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m +# Default value: -Xmx1024m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +# # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn +#Sat Aug 24 12:09:01 CEST 2019 android.useAndroidX=true -# Automatically convert third-party libraries to use AndroidX -android.enableJetifier=true -# Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official -################## -### VERSIONING ### -################## -# APP VERSION -VERSION_NAME=1.0.0 -VERSION_CODE=1 -# ANDROID BUILD SETTINGS -ANDROID_MIN_SDK_VERSION=21 -ANDROID_TARGET_SDK_VERSION=28 -ANDROID_COMPILE_SDK_VERSION=28 -ANDROID_BUILD_TOOLS_VERSION=28.0.3 -# LIBRARIES -KOTLIN_VERSION=1.3.41 -COROUTINES_VERSION=1.2.1 KOIN_VERSION=2.0.1 -RETROFIT_VERSION=2.6.0 +ANDROID_BUILD_TOOLS_VERSION=28.0.3 ROOM_VERSION=2.1.0 +COROUTINES_VERSION=1.2.1 +ANDROID_TARGET_SDK_VERSION=28 OKHTTP3LOGINTERCEPTOR_VERSION=3.10.0 +org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" +ANDROID_COMPILE_SDK_VERSION=28 +VERSION_NAME=1.0.0 +VERSION_CODE=1 +KOTLIN_VERSION=1.3.50 +RETROFIT_VERSION=2.6.0 +kotlin.code.style=official +ANDROID_MIN_SDK_VERSION=21 ARHITECTURECOMPONENTS_VERSION=2.2.0-alpha03 MOCKITO_VERSION=2.1.0 - - - +android.enableJetifier=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2ef1235..bfbdc68 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Jul 10 22:03:31 CEST 2019 +#Sat Aug 24 12:04:28 CEST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip