1 year ago
#372608
Anhdevit
Serializer for class 'Any' is not found. Mark the class as @Serializable or provide the serializer explicitly
This is my code:
override fun mergeItem(key: String, value: String): StorageResult<Nothing> {
if (!ensureSetup()) {
return StorageResult.Failure("Setup failed")
}
val changeManifest = atomic(false)
val valueOld = getValueForKey(key)
var newValue = value
if (valueOld != null) {
val mergedValue =
Json.decodeFromString<MutableMap<String, Any>>(value)
val entryValue =
Json.decodeFromString<MutableMap<String, Any>>(valueOld.toString())
if (mergeRecursive(mergedValue, entryValue)) {
newValue = Json.encodeToString(mergedValue)
}
}
writeEntry(key, newValue)
if (changeManifest.value) {
writeManifest()
}
return StorageResult.Success()
}
private fun mergeRecursive(
destination: MutableMap<String, Any>,
source: Map<String, Any>
): Boolean {
var modified = false
for ((key, value) in source) {
val sourceValue = value
val destinationValue = destination[key]
if (sourceValue is Map<*, *>) {
if (destinationValue is Map<*, *>) {
if (mergeRecursive(
destinationValue as MutableMap<String, Any>,
sourceValue as Map<String, Any>
)
) {
destination[key] = destinationValue
modified = true
}
} else {
destination[key] = sourceValue
modified = true
}
} else if (source != destinationValue) {
destination[key] = sourceValue
modified = true
}
}
return modified
}
Test case
@Test
fun testMergeAsyncStorage() {
val map = HashMap<String, String>()
map["key1"] = "value1";
map["key2"] = "value2";
map["key3"] = "value3";
val jsonAbc = Json.encodeToString(map)
AsyncStorage().setItem("jsonAbc", jsonAbc)
val map1 = HashMap<String, String>()
map1["key1"] = "value12";
map1["key2"] = "value22";
map1["key3"] = "value32";
val jsonAbc1 = Json.encodeToString(map1)
AsyncStorage().mergeItem("jsonAbc", jsonAbc1)
val res = AsyncStorage().getItem("jsonAbc")
val map1Clone = res?.let { Json.decodeFromString<HashMap<String, String>>(it) }
assert(map1["key1"] == map1Clone?.get("key1"))
}
And is show this error:
kotlinx.serialization.SerializationException: Serializer for class 'Any' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
On Kotlin/Native explicitly declared serializer should be used for interfaces and enums without @Serializable annotation
kotlinx.serialization.SerializationException: Serializer for class 'Any' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
On Kotlin/Native explicitly declared serializer should be used for interfaces and enums without @Serializable annotation
at kotlin.Throwable#<init>(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Throwable.kt:24)
at kotlin.Exception#<init>(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:23)
at kotlin.RuntimeException#<init>(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:34)
at kotlin.IllegalArgumentException#<init>(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:59)
at kotlinx.serialization.SerializationException#<init>(/opt/buildAgent/work/b2fef8360e1bcf3d/core/commonMain/src/kotlinx/serialization/SerializationException.kt:48)
at kotlinx.serialization.internal#platformSpecificSerializerNotRegistered__at__kotlin.reflect.KClass<*>(/opt/buildAgent/work/b2fef8360e1bcf3d/core/nativeMain/src/kotlinx/serialization/internal/Platform.kt:22)
at kotlinx.serialization#serializer__at__kotlinx.serialization.modules.SerializersModule(/opt/buildAgent/work/b2fef8360e1bcf3d/core/commonMain/src/kotlinx/serialization/Serializers.kt:60)
at kotlinx.serialization.builtinSerializer#internal(/opt/buildAgent/work/b2fef8360e1bcf3d/core/commonMain/src/kotlinx/serialization/Serializers.kt:96)
at kotlinx.serialization.serializerByKTypeImpl#internal(/opt/buildAgent/work/b2fef8360e1bcf3d/core/commonMain/src/kotlinx/serialization/Serializers.kt:84)
at kotlinx.serialization#serializer__at__kotlinx.serialization.modules.SerializersModule(/opt/buildAgent/work/b2fef8360e1bcf3d/core/commonMain/src/kotlinx/serialization/Serializers.kt:59)
at vn.momo.core.modules.storage.async.AsyncStorageModule#multiMerge(/Users/anhdevit/Desktop/momo-app-vix/shared/src/iosMain/kotlin/vn/momo/core/modules/storage/async/AsyncStorageModule.kt:385)
at vn.momo.core.modules.storage.async.AsyncStorage#mergeItem(/Users/anhdevit/Desktop/momo-app-vix/shared/src/iosMain/kotlin/vn/momo/core/modules/storage/async/AsyncStorage.kt:23)
at vn.momo.core.storage.async.iOSAsyncStorageTest#testMergeAsyncStorage(/Users/anhdevit/Desktop/momo-app-vix/shared/src/iosTest/kotlin/vn/momo/core/storage/async/iOSAsyncStorageTest.kt:115)
at vn.momo.core.storage.async.$iOSAsyncStorageTest$test$0.$testMergeAsyncStorage$FUNCTION_REFERENCE$23.invoke#internal(/Users/anhdevit/Desktop/momo-app-vix/shared/src/iosTest/kotlin/vn/momo/core/storage/async/iOSAsyncStorageTest.kt:120)
at vn.momo.core.storage.async.$iOSAsyncStorageTest$test$0.$testMergeAsyncStorage$FUNCTION_REFERENCE$23.$<bridge-UNNN>invoke(/Users/anhdevit/Desktop/momo-app-vix/shared/src/iosTest/kotlin/vn/momo/core/storage/async/iOSAsyncStorageTest.kt:120)
at kotlin.native.internal.test.BaseClassSuite.TestCase#run(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestSuite.kt:85)
at kotlin.native.internal.test.TestRunner.run#internal(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:245)
at kotlin.native.internal.test.TestRunner.runIteration#internal(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:271)
at kotlin.native.internal.test.TestRunner#run(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:286)
at kotlin.native.internal.test#testLauncherEntryPoint(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:30)
at kotlin.native.internal.test#main(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:34)
at <global>.Konan_start(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:33)
at <global>.Init_and_run_start(Unknown Source)
at <global>.start_sim(Unknown Source)
at <global>.0x0(Unknown Source)
Update: StorageResult
sealed class StorageResult<out T> {
data class Success<T>(val data: T? = null) : StorageResult<T>()
data class Failure(val errorMessage: String?, val throwable: Throwable? = null) : StorageResult<Nothing>()
}
import
import co.touchlab.stately.freeze
import co.touchlab.stately.isolate.IsolateState
import kotlinx.atomicfu.atomic
import platform.Foundation.*
import kotlinx.cinterop.*
import kotlinx.serialization.*
import kotlinx.serialization.json.Json
import platform.darwin.NSUInteger
private fun getValueForKey(key: String): String? {
var value = asyncStorageHolder.access {
it.manifest[key]
}
if (value == null) {
value = getCache().objectForKey(key) as String?
if (value == null) {
val filePath = filePathForKey(key)
val resultReadFile = readFile(filePath)
value = when (resultReadFile) {
is StorageResult.Success -> {
resultReadFile.data
}
is StorageResult.Failure -> {
null
}
}
getCache().setObject(value, key, value?.length as NSUInteger)
}
}
return value
}
android
ios
kotlin
kotlin-multiplatform
0 Answers
Your Answer