坚持 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 的响应,我在共享模块中的完成处理程序也永远不会被调用。
我实现的唯一解决方案是使用 expect
和 actual
机制创建不同的 HTTP 客户端。通过创建单独的客户端,我还没有遇到这个问题。
如果您有任何其他答案或解决方案,我很乐意查看。
尝试在 install(Logging) 块中设置 LogLevel.NONE。
目前我是这样解决的,因为好像是Ktor的bug
参见:https://youtrack.jetbrains.com/issue/KTOR-2711
它应该在版本 1.6.0.
中修复
我正在尝试使用 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 的响应,我在共享模块中的完成处理程序也永远不会被调用。
我实现的唯一解决方案是使用 expect
和 actual
机制创建不同的 HTTP 客户端。通过创建单独的客户端,我还没有遇到这个问题。
如果您有任何其他答案或解决方案,我很乐意查看。
尝试在 install(Logging) 块中设置 LogLevel.NONE。
目前我是这样解决的,因为好像是Ktor的bug
参见:https://youtrack.jetbrains.com/issue/KTOR-2711
它应该在版本 1.6.0.