-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cache and Eviction Strategy: Offline First #41
base: develop
Are you sure you want to change the base?
Conversation
…r 15 Min using work manager
… transform hourly and daily weather list
…t weatherinfo from the cached data
I have ran the tests bitrise is warning about and they are passing. Not sure why but I added Roboelectric test runner and they pass. |
app/build.gradle.kts
Outdated
@@ -75,7 +75,7 @@ dependencies { | |||
implementation(libs.kotlinx.serialization.converter) | |||
implementation(libs.kotlinx.serialization) | |||
implementation(libs.coil) | |||
|
|||
implementation(libs.retrofit.converter.gson) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use something modern like moshi or kotlinx.serialization
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. On it
private val gson = Gson() | ||
|
||
@TypeConverter | ||
fun fromHourlyWeatherEntityList(hourlyList: List<HourlyWeatherEntity>): String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious
Why do you want to save a list of entities as a string - is it not better to basically use relationships?
Also, avoid gson as suggested earlier
Use typeconverters only when converting data types not supported by room natively
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad. Relationships would be a better approach. Let me make the adjustments and remove gson.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution 🙌, I'll leave some comments on the go
app/src/main/java/com/github/odaridavid/weatherapp/data/weather/DefaultWeatherRepository.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/com/github/odaridavid/weatherapp/data/weather/DefaultWeatherRepository.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/com/github/odaridavid/weatherapp/worker/UpdatedWeatherWorker.kt
Outdated
Show resolved
Hide resolved
val name = "notification" | ||
val descriptionText = "description" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest more meaningful names and description on what kind of notificiations this channel provides e.g Weather Updates or something in that line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay.
# Conflicts: # app/build.gradle.kts # gradle/libs.versions.toml
# Conflicts: # app/build.gradle.kts # gradle/libs.versions.toml
@odaridavid I had updated the changes as you had requested. Kindly review. |
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## develop #41 +/- ##
==============================================
- Coverage 58.76% 46.80% -11.96%
- Complexity 31 42 +11
==============================================
Files 18 25 +7
Lines 388 611 +223
Branches 30 37 +7
==============================================
+ Hits 228 286 +58
- Misses 149 311 +162
- Partials 11 14 +3
☔ View full report in Codecov by Sentry. |
app/src/main/java/com/github/odaridavid/weatherapp/data/weather/RefreshWeatherUseCase.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/com/github/odaridavid/weatherapp/di/UseCaseModule.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/com/github/odaridavid/weatherapp/worker/UpdatedWeatherWorker.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine to me ✅, great work on pushing this.
My final comment would be the UseCase implementation should ideally sit in the core/domain and can be done in such a way that the platform-specific needs are implemented in the presentation layer, but that can be followed up later like so
class DefaultRefreshWeatherUseCase @Inject constructor(
private val weatherRepository: WeatherRepository
) : RefreshWeatherUseCase {
override operator fun invoke(
defaultLocation: DefaultLocation,
language: String,
units: String,
onSuccess: (data) -> Unit
onError: (errorType) -> Unit
): Flow<Result<Weather>> = flow{
weatherRepository.fetchWeatherData(
defaultLocation = defaultLocation,
language = language,
units =units
).collect{ result->
when (result) {
is Result.Success -> {
onSuccess(result.data)
}
is Result.Error -> {
onError(result.errorType)
}
}
}
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@odaridavid yes. There's a problem with the room relations. I am waiting for @jumaallan to help me out. |
@odaridavid I fixed the error on Workmanager. Also I had to add latitude and longitude to the weather models so I can use it on my entity. This also fixes the review @jumaallan had initially requested and removed the type converters. |
Related Issue
#21
Description
Added offline First features.
fetchWeather function from the repositiory is responsible for fetching weather data. It first checks if there is cached weather data available and if it is still valid. If so, it emits the cached data as a ApiResult.Success result. If not, it makes an API request to fetch the weather data. If the API response is successful, it converts the response to a WeatherEntity, inserts it into the local cache using the weatherDao, and emits the converted data as a ApiResult.Success result.
Finally, in the onCompletion block, it schedules a background worker (UpdateWeatherWorker) using WorkManager to refresh the weather data periodically after 15 Minutes.
How Can It Be Tested
The Test function passes and emits ApiResult.Success when fetchWeather contains the expected mapped weather data.
Screenshots (If Applicable)
N/A
Additional Comments
I also added a notification utility, so when there's a newly refreshed weather update, client gets a notification.
Checklist