diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt index b7c912c00..328cc4e0f 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt @@ -17,6 +17,8 @@ package com.google.samples.apps.nowinandroid.core.network.demo import JvmUnitTestDemoAssetManager +import android.os.Build.VERSION.SDK_INT +import android.os.Build.VERSION_CODES.M import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.network.NiaNetworkDataSource @@ -28,6 +30,7 @@ import kotlinx.coroutines.withContext import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream +import java.io.BufferedReader import javax.inject.Inject /** @@ -39,17 +42,11 @@ class DemoNiaNetworkDataSource @Inject constructor( private val assets: DemoAssetManager = JvmUnitTestDemoAssetManager, ) : NiaNetworkDataSource { - @OptIn(ExperimentalSerializationApi::class) override suspend fun getTopics(ids: List?): List = - withContext(ioDispatcher) { - assets.open(TOPICS_ASSET).use(networkJson::decodeFromStream) - } + getDataFromJsonFile(TOPICS_ASSET) - @OptIn(ExperimentalSerializationApi::class) override suspend fun getNewsResources(ids: List?): List = - withContext(ioDispatcher) { - assets.open(NEWS_ASSET).use(networkJson::decodeFromStream) - } + getDataFromJsonFile(NEWS_ASSET) override suspend fun getTopicChangeList(after: Int?): List = getTopics().mapToChangeList(NetworkTopic::id) @@ -57,6 +54,27 @@ class DemoNiaNetworkDataSource @Inject constructor( override suspend fun getNewsResourceChangeList(after: Int?): List = getNewsResources().mapToChangeList(NetworkNewsResource::id) + /** + * Get data from the given JSON [fileName]. + */ + @OptIn(ExperimentalSerializationApi::class) + private suspend inline fun getDataFromJsonFile(fileName: String): List = + withContext(ioDispatcher) { + assets.open(fileName).use { inputStream -> + if (SDK_INT <= M) { + /** + * On API 23 (M) and below we must use a workaround to avoid an exception being + * thrown during deserialization. See: + * https://github.com/Kotlin/kotlinx.serialization/issues/2457#issuecomment-1786923342 + */ + inputStream.bufferedReader().use(BufferedReader::readText) + .let(networkJson::decodeFromString) + } else { + networkJson.decodeFromStream(inputStream) + } + } + } + companion object { private const val NEWS_ASSET = "news.json" private const val TOPICS_ASSET = "topics.json"