Fast-android-networking: Kotlin Coroutine Support

Created on 19 Jan 2019  路  3Comments  路  Source: amitshekhariitbhu/Fast-Android-Networking

Fast Android Networking have been support RxJava for beginning. And can you add support for Kotlin Coroutine in this library ?

Or any tips and tricks about how to use Fast Android Networking with Kotlin Coroutine ?

Most helpful comment

I hope this will help
```kotlin
/*
CREATED BY : yogesh ON 07/08/20 10:58 AM
*/

open class BaseCaller {

val params: HashMap<String, String> by lazy {
    HashMap<String, String>()
}

val files: HashMap<String, File?> by lazy {
    HashMap<String, File?>()
}

suspend fun hitApiGet(
    api: String,
    params: HashMap<String, String>? = null, checkAuthentication: Boolean = true
): Resource<BaseApiModel> {
    return hitApiGet(api, params, BaseApiModel::class.java,checkAuthentication)
}

suspend fun <T> hitApiGet(
    api: String,
    params: HashMap<String, String>? = null,
    objectType: Class<T>, checkAuthentication: Boolean = true
): Resource<T> {
    val request = AndroidNetworking.get(api)
        .addQueryParameter(params)
        .addHeaders(getHeader())
        .build()

    return request.fetch(objectType,checkAuthentication)
}

suspend fun hitApiUpload(
    api: String,
    params: HashMap<String, String>? = null,
    files: HashMap<String, File?>? = null, checkAuthentication: Boolean = true
): Resource<BaseApiModel> {
    return hitApiUpload(api, params, files, BaseApiModel::class.java, checkAuthentication)
}

suspend fun <T> hitApiUpload(
    api: String,
    params: HashMap<String, String>? = null,
    files: HashMap<String, File?>? = null,
    objectType: Class<T>, checkAuthentication: Boolean = true
): Resource<T> {
    val request = AndroidNetworking.upload(api)
        .addMultipartParameter(params)
        .addMultipartFile(files)
        .setOkHttpClient(OkHttpClient())
        .addHeaders(getHeader())
        .build()

    return request.fetch(objectType,checkAuthentication)
}

private suspend fun <T> ANRequest<*>.fetch(objectType: Class<T>,checkAuthentication: Boolean): Resource<T> = withContext(Dispatchers.IO){
    val response = executeForObject(BaseApiModel::class.java)
    try {
        if (response.isSuccess) {
            if (response.result is BaseApiModel) {
                val baseApiModel = response.result as BaseApiModel
                if (baseApiModel.code == 200) {
                    if (objectType.isAssignableFrom(BaseApiModel::class.java))
                        return@withContext Resource.success<T>(baseApiModel as T, baseApiModel.message)
                    val formatted = Gson().fromJson(baseApiModel.data, objectType)
                    return@withContext  Resource.success<T>(formatted, baseApiModel.message)
                } else {
                    return@withContext  onGettingError(ANError().apply {
                        errorCode = baseApiModel.code
                        this.errorBody = Gson().toJson(baseApiModel).toString()
                    },checkAuthentication)
                }
            } else {
                return@withContext  Resource.error<T>("Some error occurred")
            }
        }
    }catch (e:Exception){
        e.printStackTrace()
        return@withContext  Resource.error<T>("Some error occurred")
    }
    return@withContext  onGettingError(response.error,checkAuthentication)
}

suspend fun hitApi(
    api: String,
    params: HashMap<String, String>? = null, checkAuthentication: Boolean = true,headers: HashMap<String, String>? = null
): Resource<BaseApiModel> {
    return hitApi(api, params, BaseApiModel::class.java, checkAuthentication,headers)
}

suspend fun <T> hitApi(
    api: String,
    params: HashMap<String, String>? = null,
    objectType: Class<T>, checkAuthentication: Boolean = true, headers: HashMap<String, String>? = null
): Resource<T> {

    val request = AndroidNetworking.post(api)
        .addBodyParameter(params)
        .addHeaders(getHeader())
        .addHeaders(headers)
        .build()

    return request.fetch(objectType,checkAuthentication)
}


private fun <T> onGettingError(anError: ANError, checkAuthentication: Boolean): Resource<T> {
     if (anError.errorCode == 401) {
         if (checkAuthentication)
             MyApplication.getInstance().logout()
         return Resource.error<T>("User Logout")
     } else if (anError.errorCode != 0) {
        // received error from server
        // error.getErrorCode() - the error code from server
        // error.getErrorBody() - the error body from server
        // error.getErrorDetail() - just an error detail
        //Log.d(TAG, "onError errorCode : " + anError.getErrorCode());
        //Log.d(TAG, "onError errorBody : " + anError.getErrorBody());
        //Log.d(TAG, "onError errorDetail : " + anError.getErrorDetail());
        // get parsed error object (If ApiError is your class)
        try {
            LogHelper.logD("Error",anError.errorBody)
            val apiError = anError.getErrorAsObject(BaseApiModel::class.java)
            return Resource.error<T>(apiError.message)
        } catch (e: Exception) {
            return Resource.error<T>("Parsing Error")
            e.printStackTrace()
        }
    } else {
        // error.getErrorDetail() : connectionError, parseError, requestCancelledError
        //Log.d(TAG, "onError errorDetail : " + anError.getErrorDetail());
        return when (anError.errorDetail) {
            ANConstants.REQUEST_CANCELLED_ERROR -> Resource.error<T>("Request Cancelled")
            ANConstants.CONNECTION_ERROR -> Resource.error<T>("No internet connected")
            else -> Resource.error<T>("Some Error occurred")
        }
    }
}


protected fun getHeader(): HashMap<String, String> {
    val map = HashMap<String, String>()
    map.put("platform", "A")
    map.put("os_version", Build.VERSION.SDK_INT.toString())
   // map["device_id"] = getDeviceId()
   // map["X-localization"] = PreferenceLocaleStore(MyApplication.getInstance(), Locale(Languages.ENGLISH)).getLocale().language
    map["app_version"] = BuildConfig.VERSION_NAME
    map["time"] = System.currentTimeMillis().toString()
    map["timezone"] = TimeZone.getDefault().id
    map["Accept"] = "application/json"
    val token = MyApplication.getInstance().getLoginToken()
    if (!token.trim().isBlank())
        map["Authorization"] = "Bearer $token"
    return map
}

}`

All 3 comments

If I'm not mistaken, you can create a synchronous request, so you can wrap it in a coroutine scope.

CoroutineScope(Dispatcher.Main).launch { synchronousRequest() }

Is there anyone has an example of how to implement Fast Android Networking with Kotlin Coroutine?

I hope this will help
```kotlin
/*
CREATED BY : yogesh ON 07/08/20 10:58 AM
*/

open class BaseCaller {

val params: HashMap<String, String> by lazy {
    HashMap<String, String>()
}

val files: HashMap<String, File?> by lazy {
    HashMap<String, File?>()
}

suspend fun hitApiGet(
    api: String,
    params: HashMap<String, String>? = null, checkAuthentication: Boolean = true
): Resource<BaseApiModel> {
    return hitApiGet(api, params, BaseApiModel::class.java,checkAuthentication)
}

suspend fun <T> hitApiGet(
    api: String,
    params: HashMap<String, String>? = null,
    objectType: Class<T>, checkAuthentication: Boolean = true
): Resource<T> {
    val request = AndroidNetworking.get(api)
        .addQueryParameter(params)
        .addHeaders(getHeader())
        .build()

    return request.fetch(objectType,checkAuthentication)
}

suspend fun hitApiUpload(
    api: String,
    params: HashMap<String, String>? = null,
    files: HashMap<String, File?>? = null, checkAuthentication: Boolean = true
): Resource<BaseApiModel> {
    return hitApiUpload(api, params, files, BaseApiModel::class.java, checkAuthentication)
}

suspend fun <T> hitApiUpload(
    api: String,
    params: HashMap<String, String>? = null,
    files: HashMap<String, File?>? = null,
    objectType: Class<T>, checkAuthentication: Boolean = true
): Resource<T> {
    val request = AndroidNetworking.upload(api)
        .addMultipartParameter(params)
        .addMultipartFile(files)
        .setOkHttpClient(OkHttpClient())
        .addHeaders(getHeader())
        .build()

    return request.fetch(objectType,checkAuthentication)
}

private suspend fun <T> ANRequest<*>.fetch(objectType: Class<T>,checkAuthentication: Boolean): Resource<T> = withContext(Dispatchers.IO){
    val response = executeForObject(BaseApiModel::class.java)
    try {
        if (response.isSuccess) {
            if (response.result is BaseApiModel) {
                val baseApiModel = response.result as BaseApiModel
                if (baseApiModel.code == 200) {
                    if (objectType.isAssignableFrom(BaseApiModel::class.java))
                        return@withContext Resource.success<T>(baseApiModel as T, baseApiModel.message)
                    val formatted = Gson().fromJson(baseApiModel.data, objectType)
                    return@withContext  Resource.success<T>(formatted, baseApiModel.message)
                } else {
                    return@withContext  onGettingError(ANError().apply {
                        errorCode = baseApiModel.code
                        this.errorBody = Gson().toJson(baseApiModel).toString()
                    },checkAuthentication)
                }
            } else {
                return@withContext  Resource.error<T>("Some error occurred")
            }
        }
    }catch (e:Exception){
        e.printStackTrace()
        return@withContext  Resource.error<T>("Some error occurred")
    }
    return@withContext  onGettingError(response.error,checkAuthentication)
}

suspend fun hitApi(
    api: String,
    params: HashMap<String, String>? = null, checkAuthentication: Boolean = true,headers: HashMap<String, String>? = null
): Resource<BaseApiModel> {
    return hitApi(api, params, BaseApiModel::class.java, checkAuthentication,headers)
}

suspend fun <T> hitApi(
    api: String,
    params: HashMap<String, String>? = null,
    objectType: Class<T>, checkAuthentication: Boolean = true, headers: HashMap<String, String>? = null
): Resource<T> {

    val request = AndroidNetworking.post(api)
        .addBodyParameter(params)
        .addHeaders(getHeader())
        .addHeaders(headers)
        .build()

    return request.fetch(objectType,checkAuthentication)
}


private fun <T> onGettingError(anError: ANError, checkAuthentication: Boolean): Resource<T> {
     if (anError.errorCode == 401) {
         if (checkAuthentication)
             MyApplication.getInstance().logout()
         return Resource.error<T>("User Logout")
     } else if (anError.errorCode != 0) {
        // received error from server
        // error.getErrorCode() - the error code from server
        // error.getErrorBody() - the error body from server
        // error.getErrorDetail() - just an error detail
        //Log.d(TAG, "onError errorCode : " + anError.getErrorCode());
        //Log.d(TAG, "onError errorBody : " + anError.getErrorBody());
        //Log.d(TAG, "onError errorDetail : " + anError.getErrorDetail());
        // get parsed error object (If ApiError is your class)
        try {
            LogHelper.logD("Error",anError.errorBody)
            val apiError = anError.getErrorAsObject(BaseApiModel::class.java)
            return Resource.error<T>(apiError.message)
        } catch (e: Exception) {
            return Resource.error<T>("Parsing Error")
            e.printStackTrace()
        }
    } else {
        // error.getErrorDetail() : connectionError, parseError, requestCancelledError
        //Log.d(TAG, "onError errorDetail : " + anError.getErrorDetail());
        return when (anError.errorDetail) {
            ANConstants.REQUEST_CANCELLED_ERROR -> Resource.error<T>("Request Cancelled")
            ANConstants.CONNECTION_ERROR -> Resource.error<T>("No internet connected")
            else -> Resource.error<T>("Some Error occurred")
        }
    }
}


protected fun getHeader(): HashMap<String, String> {
    val map = HashMap<String, String>()
    map.put("platform", "A")
    map.put("os_version", Build.VERSION.SDK_INT.toString())
   // map["device_id"] = getDeviceId()
   // map["X-localization"] = PreferenceLocaleStore(MyApplication.getInstance(), Locale(Languages.ENGLISH)).getLocale().language
    map["app_version"] = BuildConfig.VERSION_NAME
    map["time"] = System.currentTimeMillis().toString()
    map["timezone"] = TimeZone.getDefault().id
    map["Accept"] = "application/json"
    val token = MyApplication.getInstance().getLoginToken()
    if (!token.trim().isBlank())
        map["Authorization"] = "Bearer $token"
    return map
}

}`

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alitong picture alitong  路  8Comments

everyline picture everyline  路  9Comments

amervelic picture amervelic  路  4Comments

stridercheng picture stridercheng  路  6Comments

ExploiTR picture ExploiTR  路  7Comments