Skip to content

Commit

Permalink
[#20] Integrate Realm Kotlin to save survey data in local storage
Browse files Browse the repository at this point in the history
  • Loading branch information
luongvo committed Mar 5, 2023
1 parent f07cef6 commit 6ca1db3
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 8 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ buildscript {
classpath(Dependencies.Kotlin.KOTLIN_GRADLE_PLUGIN)
classpath(Dependencies.Kotlin.KOTLIN_SERIALIZATION)
classpath(Dependencies.Firebase.GOOGLE_SERVICES)
classpath(Dependencies.Storage.REALM_GRADLE_PLUGIN)
}
}

Expand Down
2 changes: 2 additions & 0 deletions buildSrc/src/main/java/Configurations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ object Plugins {
const val KSP = "com.google.devtools.ksp"

const val MULTIPLATFORM = "multiplatform"

const val REALM = "io.realm.kotlin"
}

object XcodeConfiguration {
Expand Down
7 changes: 6 additions & 1 deletion buildSrc/src/main/java/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ object Versions {

const val NAPIER = "2.6.1"

const val REALM = "1.6.1"

const val SETTINGS = "1.0.0-RC"

const val TIMBER = "4.7.1"
Expand Down Expand Up @@ -119,7 +121,10 @@ object Dependencies {
const val JSON_API = "co.nimblehq.jsonapi:core:${Versions.JSON_API}"
}

object Settings {
object Storage {
const val REALM_GRADLE_PLUGIN = "io.realm.kotlin:gradle-plugin:${Versions.REALM}"
const val REALM_CORE = "io.realm.kotlin:library-base:${Versions.REALM}"

const val SETTINGS = "com.russhwolf:multiplatform-settings:${Versions.SETTINGS}"
}

Expand Down
4 changes: 3 additions & 1 deletion shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ plugins {
id(Plugins.KOVER)
id(Plugins.KSP).version(Versions.KSP)
id(Plugins.KOTLINX_RESOURCES).version(Versions.KOTLINX_RESOURCES)
id(Plugins.REALM)
}

kotlin {
Expand Down Expand Up @@ -48,7 +49,8 @@ kotlin {
implementation(AUTH)
implementation(JSON_API)
}
implementation(Dependencies.Settings.SETTINGS)
implementation(Dependencies.Storage.SETTINGS)
implementation(Dependencies.Storage.REALM_CORE)
implementation(Dependencies.Log.NAPIER)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package vn.luongvo.kmm.survey.data.local.datasource

import io.realm.kotlin.Realm
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import vn.luongvo.kmm.survey.data.local.model.SurveyRealmObject

interface SurveyLocalDataSource {

fun saveSurveys(surveys: List<SurveyRealmObject>)
}

class SurveyLocalDataSourceImpl(private val realm: Realm) : SurveyLocalDataSource {

override fun saveSurveys(surveys: List<SurveyRealmObject>) {
realm.writeBlocking {
surveys.forEach {
copyToRealm(it, updatePolicy = UpdatePolicy.ALL)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package vn.luongvo.kmm.survey.data.local.model

import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PrimaryKey
import vn.luongvo.kmm.survey.domain.model.Survey

class SurveyRealmObject : RealmObject {

@PrimaryKey
var id: String = ""
var title: String = ""
var description: String = ""
var coverImageUrl: String = ""

constructor(
id: String,
title: String,
description: String,
coverImageUrl: String
) : this() {
this.id = id
this.title = title
this.description = description
this.coverImageUrl = coverImageUrl
}

constructor()
}

fun SurveyRealmObject.toSurvey() = Survey(
id = id,
title = title,
description = description,
coverImageUrl = coverImageUrl,
questions = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package vn.luongvo.kmm.survey.data.local.realm

import io.realm.kotlin.Realm
import io.realm.kotlin.RealmConfiguration
import vn.luongvo.kmm.survey.data.local.model.SurveyRealmObject

val realm: Realm by lazy {
val configuration = RealmConfiguration.create(schema = setOf(SurveyRealmObject::class))
Realm.open(configuration)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,27 @@ package vn.luongvo.kmm.survey.data.repository

import kotlinx.coroutines.flow.Flow
import vn.luongvo.kmm.survey.data.extensions.flowTransform
import vn.luongvo.kmm.survey.data.local.datasource.SurveyLocalDataSource
import vn.luongvo.kmm.survey.data.remote.datasource.SurveyRemoteDataSource
import vn.luongvo.kmm.survey.data.remote.model.request.SurveySubmissionRequestBody
import vn.luongvo.kmm.survey.data.remote.model.response.toSurvey
import vn.luongvo.kmm.survey.domain.model.Survey
import vn.luongvo.kmm.survey.domain.model.SurveySubmission
import vn.luongvo.kmm.survey.domain.model.*
import vn.luongvo.kmm.survey.domain.repository.SurveyRepository

class SurveyRepositoryImpl(
private val surveyRemoteDataSource: SurveyRemoteDataSource
private val surveyRemoteDataSource: SurveyRemoteDataSource,
private val surveyLocalDataSource: SurveyLocalDataSource
) : SurveyRepository {

override fun getSurveys(pageNumber: Int, pageSize: Int, isRefresh: Boolean): Flow<List<Survey>> = flowTransform {
// TODO clear surveys cache when isRefresh = true
surveyRemoteDataSource
val surveys = surveyRemoteDataSource
.getSurveys(pageNumber = pageNumber, pageSize = pageSize)
.map { it.toSurvey() }

surveyLocalDataSource.saveSurveys(surveys.map { it.toSurveyRealmObject() })

surveys
}

override fun getSurveyDetail(id: String): Flow<Survey> = flowTransform {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package vn.luongvo.kmm.survey.di.module
import org.koin.core.module.dsl.bind
import org.koin.core.module.dsl.singleOf
import org.koin.dsl.module
import vn.luongvo.kmm.survey.data.local.datasource.TokenLocalDataSource
import vn.luongvo.kmm.survey.data.local.datasource.TokenLocalDataSourceImpl
import vn.luongvo.kmm.survey.data.local.datasource.*
import vn.luongvo.kmm.survey.data.local.realm.realm

val localModule = module {
single { realm }
singleOf(::TokenLocalDataSourceImpl) { bind<TokenLocalDataSource>() }
singleOf(::SurveyLocalDataSourceImpl) { bind<SurveyLocalDataSource>() }
}

0 comments on commit 6ca1db3

Please sign in to comment.