Search code examples
iosswiftkotlin-multiplatformktorkotlin-multiplatform-mobile

Stuck with Api response Ktor


I am trying to build a KMM application using Ktor for our ApiServices. I have created a BaseApiClass where I have all of the api related code.

Code for 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)
    }
}

Here's how I call the api from iOS app :-

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 
            })
        }
    }

Now here if I try to call similar few more api's with the same object i.e apiClass then after few calls it get stuck inside my function callApi it don't send even api request (Because I can't see Request Logs printed in my console) and because of that I cannot do any other operations as I don't get anything from api.

As soon as I change my screen or close the app and try to call the same api then it works good.

But instead of creating a object only at one time like this apiClass = BaseApiClass() if I try to do with BaseApiClass().sampleApi(request params here) {// completion handler here} it works fine I don't get any issues with this.

I am not sure what causes this to happen everything works good in Android this is faced only with iOS.


Solution

  • After all the efforts and trying a lot of debugging skills I got to understand that my completion handler in the shared module is never called even if I receive the response the response from api.

    The only solution I have achieved is creating the different HTTP Client using expect and actual mechanism. By making separate clients I have not encountered the issue yet.

    If you have any other answers or solutions I would be happy to have a look at it.