iOS decode json

This commit is contained in:
Syer10
2023-02-14 22:30:51 -05:00
parent c42310e5a0
commit 125d9b7a3e
6 changed files with 61 additions and 16 deletions

View File

@@ -26,10 +26,10 @@ import me.tatarka.inject.annotations.Provides
interface DataComponent { interface DataComponent {
@Provides @Provides
fun ktorfit(http: Http, serverPreferences: ServerPreferences) = Ktorfit fun ktorfit(http: Http, serverPreferences: ServerPreferences, flowIOResponseConverter: FlowIOResponseConverter) = Ktorfit
.Builder() .Builder()
.httpClient(http) .httpClient(http)
.responseConverter(FlowIOResponseConverter()) .responseConverter(flowIOResponseConverter)
.baseUrl(serverPreferences.serverUrl().get().toString().addSuffix('/')) .baseUrl(serverPreferences.serverUrl().get().toString().addSuffix('/'))
.build() .build()

View File

@@ -10,14 +10,15 @@ import ca.gosyer.jui.core.lang.IO
import de.jensklingenberg.ktorfit.Ktorfit import de.jensklingenberg.ktorfit.Ktorfit
import de.jensklingenberg.ktorfit.converter.request.ResponseConverter import de.jensklingenberg.ktorfit.converter.request.ResponseConverter
import de.jensklingenberg.ktorfit.internal.TypeData import de.jensklingenberg.ktorfit.internal.TypeData
import io.ktor.client.call.body
import io.ktor.client.statement.HttpResponse import io.ktor.client.statement.HttpResponse
import io.ktor.util.reflect.TypeInfo import io.ktor.util.reflect.TypeInfo
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.serialization.json.Json
import me.tatarka.inject.annotations.Inject
class FlowIOResponseConverter : ResponseConverter { class FlowIOResponseConverter @Inject constructor(private val json: Json) : ResponseConverter {
override fun supportedType(typeData: TypeData, isSuspend: Boolean): Boolean { override fun supportedType(typeData: TypeData, isSuspend: Boolean): Boolean {
return typeData.qualifiedName == "kotlinx.coroutines.flow.Flow" return typeData.qualifiedName == "kotlinx.coroutines.flow.Flow"
@@ -34,7 +35,7 @@ class FlowIOResponseConverter : ResponseConverter {
if (info.type == HttpResponse::class) { if (info.type == HttpResponse::class) {
emit(response!!) emit(response!!)
} else { } else {
emit(response!!.body(info)) emit(decodeType(response!!, info, json))
} }
} catch (exception: Exception) { } catch (exception: Exception) {
throw exception throw exception
@@ -42,3 +43,5 @@ class FlowIOResponseConverter : ResponseConverter {
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
} }
} }
expect suspend fun decodeType(response: HttpResponse, typeInfo: TypeInfo, json: Json): Any

View File

@@ -0,0 +1,17 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.data
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.bodyAsText
import io.ktor.util.reflect.TypeInfo
import kotlinx.serialization.json.Json
import kotlinx.serialization.serializer
actual suspend fun decodeType(response: HttpResponse, typeInfo: TypeInfo, json: Json): Any {
return json.decodeFromString(serializer(typeInfo.kotlinType!!), response.bodyAsText())!!
}

View File

@@ -0,0 +1,16 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.data
import io.ktor.client.call.body
import io.ktor.client.statement.HttpResponse
import io.ktor.util.reflect.TypeInfo
import kotlinx.serialization.json.Json
actual suspend fun decodeType(response: HttpResponse, typeInfo: TypeInfo, json: Json): Any {
return response.body(typeInfo)
}

View File

@@ -22,6 +22,7 @@ import ca.gosyer.jui.domain.source.service.CatalogPreferences
import ca.gosyer.jui.domain.ui.service.UiPreferences import ca.gosyer.jui.domain.ui.service.UiPreferences
import ca.gosyer.jui.domain.updates.interactor.UpdateChecker import ca.gosyer.jui.domain.updates.interactor.UpdateChecker
import ca.gosyer.jui.domain.updates.service.UpdatePreferences import ca.gosyer.jui.domain.updates.service.UpdatePreferences
import kotlinx.serialization.json.Json
import me.tatarka.inject.annotations.Provides import me.tatarka.inject.annotations.Provides
interface SharedDomainComponent : CoreComponent { interface SharedDomainComponent : CoreComponent {
@@ -58,6 +59,8 @@ interface SharedDomainComponent : CoreComponent {
val serverListeners: ServerListeners val serverListeners: ServerListeners
val json: Json
@get:AppScope @get:AppScope
@get:Provides @get:Provides
val serverPreferencesFactory: ServerPreferences val serverPreferencesFactory: ServerPreferences
@@ -103,7 +106,7 @@ interface SharedDomainComponent : CoreComponent {
@get:AppScope @get:AppScope
@get:Provides @get:Provides
val httpFactory: Http val httpFactory: Http
get() = httpProvider.get(serverPreferences) get() = httpProvider.get()
@get:AppScope @get:AppScope
@get:Provides @get:Provides
@@ -119,4 +122,14 @@ interface SharedDomainComponent : CoreComponent {
@get:Provides @get:Provides
val serverListenersFactory: ServerListeners val serverListenersFactory: ServerListeners
get() = ServerListeners() get() = ServerListeners()
@get:AppScope
@get:Provides
val jsonFactory: Json
get() = Json {
isLenient = false
ignoreUnknownKeys = true
allowSpecialFloatingPointValues = true
useArrayPolymorphism = false
}
} }

View File

@@ -41,8 +41,11 @@ expect val Engine: HttpClientEngineFactory<HttpClientEngineConfig>
expect fun HttpClientConfig<HttpClientEngineConfig>.configurePlatform() expect fun HttpClientConfig<HttpClientEngineConfig>.configurePlatform()
class HttpProvider @Inject constructor() { class HttpProvider @Inject constructor(
fun get(serverPreferences: ServerPreferences): Http { private val serverPreferences: ServerPreferences,
private val json: Json
) {
fun get(): Http {
return HttpClient(Engine) { return HttpClient(Engine) {
configurePlatform() configurePlatform()
@@ -95,14 +98,7 @@ class HttpProvider @Inject constructor() {
socketTimeoutMillis = 2.minutes.inWholeMilliseconds socketTimeoutMillis = 2.minutes.inWholeMilliseconds
} }
install(ContentNegotiation) { install(ContentNegotiation) {
json( json(json)
Json {
isLenient = false
ignoreUnknownKeys = true
allowSpecialFloatingPointValues = true
useArrayPolymorphism = false
}
)
} }
install(WebSockets) install(WebSockets)
install(Logging) { install(Logging) {