坚持使用 Api 响应 Ktor

问题描述

我正在尝试使用 Ktor 为我们的 ApiServices 构建 KMM 应用程序。我创建了一个 BaseApiClass,其中包含所有与 API 相关的代码

BaseApiClass代码:-

class BaseAPIClass {

//Create Http Client
private val httpClient by lazy {
    HttpClient {
        defaultRequest {
            host = ApiEndPoints.Base.url
            contentType(ContentType.Application.Json)
            header(CONNECTION,CLOSE)
        }
        install(Logging) {
            logger = Logger.DEFAULT
            level = LogLevel.ALL
        }
        install(HttpTimeout) {
            requestTimeoutMillis = NETWORK_REQUEST_TIMEOUT
        }
        expectSuccess = false
        // JSON Deserializer
        install(JsonFeature) {
            val json = Json {
                ignoreUnkNownKeys = true
                coerceInputValues = true
            }
            serializer = KotlinxSerializer(json)
        }
    }
}


// Api Calling Functions I have few more similar to this but issue is random and comes in any of the api
@Throws(Exception::class)
suspend fun sampleApi(requestBody: RequestBody?) : Either<CustomException,BaseResponse<EmptyResponseModel>> {
    return try {
        val response = httpClient.post<BaseResponse<EmptyResponseModel>> {
            url(ApiEndPoints.sample.url)
            if (requestBody != null) {
                body = requestBody
            }
        }
        Success(response)
    }
    catch (e: Exception) {
        Failure(e as CustomException)
    }
}

这是我从 iOS 应用程序调用 api 的方法:-

val apiClass = BaseApiClass()

func callApi() {
        apiClass.sampleApi(requestBody: .init(string: "value here")) { (result,error) in
            result?.fold(Failed: { (error) -> Any? in
                // Error here 
            },succeeded: { (result) -> Any? in
                // Success here 
            })
        }
    }

现在,如果我尝试使用相同的 objectapiClass 调用类似的更多 api,那么在几次调用后它会卡在我的函数 callApi 中,它甚至不发送 api请求(因为我看不到控制台中打印的请求日志),因此我无法执行任何其他操作,因为我没有从 api 中获得任何东西。

只要我更换屏幕或关闭应用程序并尝试调用相同的 api,它就会运行良好。

但是,如果我尝试使用 apiClass = BaseApiClass(),它不会像这样只在一次创建一个对象 BaseApiClass().sampleApi(request params here) {// completion handler here},它可以正常工作,我不会遇到任何问题。

我不确定是什么导致了这种情况的发生,在 Android 中一切正常,这仅适用于 iOS

解决方法

您在使用 Coroutines 库的多线程变体吗?官方文档指出在使用 Ktor 时应该使用此变体。见here

,

经过所有努力并尝试了大量调试技巧后,我明白了共享模块中的完成处理程序永远不会被调用,即使我收到来自 api 的响应。

我实现的唯一解决方案是使用 expectactual 机制创建不同的 HTTP 客户端。通过制作单独的客户端,我还没有遇到过这个问题。

如果您有任何其他答案或解决方案,我很乐意查看。

,

尝试在 install(Logging) 块中设置 LogLevel.NONE
目前我是这样解决的,因为好像是Ktor的一个bug。
请参阅:https://youtrack.jetbrains.com/issue/KTOR-2711
它应该在 1.6.0 版本中修复。