https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
g

galex

05/05/2019, 4:27 AM
I have an issue with ktor-client on iOS, where I get the following error:
Copy code
kotlin.NotImplementedError: An operation is not implemented: Obtaining serializer from KClass is not available on native due to the lack of reflection. Use .serializer() directly on serializable class.
        at 0   mu51k-ios                           0x0000000108ff28a5 kfun:kotlin.Error.<init>(kotlin.String?)kotlin.Error + 21
        at 1   mu51k-ios                           0x00000001090f8bd5 kfun:kotlin.NotImplementedError.<init>(kotlin.String)kotlin.NotImplementedError + 21
        at 2   mu51k-ios                           0x0000000109134802 kfun:kotlinx.serialization.compiledSerializer@kotlin.reflect.KClass<#GENERIC_kotlin.Any>.()Generic + 226
        at 3   mu51k-ios                           0x00000001091342c1 kfun:kotlinx.serialization.serializer@kotlin.reflect.KClass<#GENERIC_kotlin.Any>.()Generic + 97
        at 4   mu51k-ios                           0x000000010913e9b0 kfun:kotlinx.serialization.modules.getContextualOrDefault@kotlinx.serialization.modules.SerialModule.(kotlin.reflect.KClass<#GENERIC_kotlin.Any>)Generic + 144
        at 5   mu51k-ios                           0x000000010913dbf8
It’s weird because the type response the API returns is indeed registered:
Copy code
actual val networkHttpClient: HttpClient
    get() = HttpClient {
        install(JsonFeature) {
            serializer = KotlinxSerializer().apply {
                setMapper(CheckEmailResponse::class, CheckEmailResponse.serializer())
                setMapper(AuthResponse::class, AuthResponse.serializer())
                setMapper(ActionResponse::class, ActionResponse.serializer())
            }
        }
    }
Does this error mean the http-client doesn’t know what to do with String? Are we supposed to register simple types ourselves?
@sandwwraith Hi, what could be the reasons for the serialiser to fail although I did set up the correct class in iOS? The network request looks like this
Copy code
val address = Url("$baseUrl/$API/$AUTH/$CREATE")
        GlobalScope.launch(backgroundDispatcher) {
            val result: AuthResponse = <http://networkHttpClient.post|networkHttpClient.post> {
                url(address.toString())
                body = TextContent(
                    Json.stringify(CreateAccountParameters(email, password, reEnterPassword)),
                    contentType = ContentType.Application.Json
                )
            }

            GlobalScope.launch(foregroundDispatcher) {
                block(result)
            }
        }
Any help would be greatly appreciated!
l

Lawik

05/06/2019, 8:06 AM
Does your response class contain generics?
g

galex

05/06/2019, 10:59 AM
Nope, here is that class:
Copy code
@Serializable
data class AuthResponse(val token: String, val userId: Int? = null)
@Lawik @sandwwraith Found the issue, finally. I used
Json.stringify(CreateAccountParameters(email, password, reEnterPassword))
instead of
Json.stringify(CreateAccountParameters.serializer(), CreateAccountParameters(email, password, reEnterPassword)),
. Gosh that was a difficult one to find…
@Lawik @sandwwraith Will serializers always have to be defined manually for iOS? Is there a planned enhancement where there is no need to do so?
s

sandwwraith

05/14/2019, 8:17 PM
Exception message contains phrase
Use .serializer() directly on serializable class.
, or was it missing? Unfortunately, there is a very limited possibilities to enhance this since reflection is almost impossible on Native
g

galex

05/15/2019, 9:24 AM
@sandwwraith It was there indeed. Was confused me in this case is that it was not on the receiving part but on the sending part, when I called
Json.stringify(…)
. Understood, so it’s better to always use
.serializer
and if so, better to do it in the common code already for all platforms. correct?
s

sandwwraith

05/15/2019, 9:34 AM
Yes
g

galex

05/15/2019, 2:35 PM
Cool, thanks