坚持 Api 响应 Ktor

Stuck with Api response 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 
            })
        }
    }

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

只要我更换屏幕或关闭应用程序并尝试调用相同的 api,它就会正常工作。

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

我不确定是什么原因导致这种情况发生在 Android 中一切正常,这只面临 iOS

您使用的是 Coroutines 库的多线程变体吗?官方文档声明你在使用 Ktor 时应该使用这个变体。参见 here

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

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

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

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

中修复