Skip to content

Instantly share code, notes, and snippets.

@NitinPraksash9911
Created January 15, 2021 18:31
Show Gist options
  • Save NitinPraksash9911/0ec4357a2fcd88025ab7537f6cb4bd7f to your computer and use it in GitHub Desktop.
Save NitinPraksash9911/0ec4357a2fcd88025ab7537f6cb4bd7f to your computer and use it in GitHub Desktop.
@Singleton
class ApiFactory @Inject constructor() {
/**
* [apiBaseUrl]
* because we are adding it from parameter in the request
* */
private val apiBaseUrl = BuildConfig.BASE_URL
private var retrofit: Retrofit? = null
/**
* open socket using retrofit for network req/response.
*
* @param serviceClass
* @param <S>
* @return
</S> */
fun <S> createService(serviceClass: Class<S>?): S {
if (retrofit == null) {
buildClient()
}
return retrofit!!.create(serviceClass!!)
}
/**
* retrofit builder for applying converters, base url etc.
*
* @param this@createBuilder
* @return
*/
private fun String.createBuilder(): Retrofit.Builder {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
.baseUrl(this)
}
/**
*
* @param this@buildClient
* */
private fun buildClient() {
val logging = HttpLoggingInterceptor()
logging.level = HttpLoggingInterceptor.Level.BODY
val builder = apiBaseUrl.createBuilder()
val httpClient =
httpClientBuilder
if (!httpClient.interceptors().contains(logging)) {
httpClient.addInterceptor(logging)
}
if (!httpClient.interceptors().contains(networkInterceptor)) {
httpClient.addNetworkInterceptor(networkInterceptor)
}
if (!httpClient.interceptors().contains(internetConnectionInterceptor)) {
httpClient.addInterceptor(internetConnectionInterceptor)
}
builder.client(httpClient.build())
retrofit = builder.build()
}
/**
* [httpClientBuilder]
* creating okHttp client builder with some constant parameters
* */
private val httpClientBuilder: OkHttpClient.Builder
get() {
val httpClient = OkHttpClient.Builder()
httpClient.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
.writeTimeout(WRITE_TIME_OUT, TimeUnit.SECONDS)
.readTimeout(READ_TIME_OUT, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.followSslRedirects(true)
.followRedirects(true)
return httpClient
}
/**
* [networkInterceptor]
*network interceptor is useful if user making a request more than once in given maxAge()
* NOTE: it is only going to use when network is available
* */
private val networkInterceptor: Interceptor
get() =
Interceptor {
val response = it.proceed(it.request())
val cacheControl = CacheControl.Builder()
.maxAge(NETWORK_INTERCEPTOR_MAX_AGE, TimeUnit.SECONDS)
.build()
response.newBuilder()
/**
*[HEADER_PRAGMA]->it is a header attached to http request and tell the request not to use caching ever
* so that's why we removing it as we want the request to cache for 5 seconds
* */
.removeHeader(HEADER_PRAGMA)
/**
* when we request okHttp call a default cache control comes from the server which contain
* header [HEADER_CACHE_CONTROL]
* so what we are doing here, we removing header comes from the sever and apply our own cache control header
* */
.removeHeader(HEADER_CACHE_CONTROL)
.header(HEADER_CACHE_CONTROL, cacheControl.toString())
.build()
}
/**
* [internetConnectionInterceptor] check availability of internet
* if not then show custom error defined below
* */
private val internetConnectionInterceptor: Interceptor
get() = Interceptor { chain ->
if (!NewsApplication.getNetworkStatus()) {
throw NoConnectivityException()
} else if (!isInternetAvailable()) {
throw NoInternetException()
} else {
chain.proceed(chain.request())
}
}
/**
* check speed of internet is very slow and return below [CustomExceptionClass]
* [NoConnectivityException], [NoInternetException]
* */
private fun isInternetAvailable(): Boolean {
return try {
val timeoutMs = 1500
val sock = Socket()
val sockaddr = InetSocketAddress("8.8.8.8", 53)
sock.connect(sockaddr, timeoutMs)
sock.close()
true
} catch (e: IOException) {
false
}
}
/**
* [CustomExceptionClass] throws when internet connectivity is very slow
* */
private class NoConnectivityException : IOException() {
override val message: String
get() = "No internet available, please check your WiFi or Data connection"
}
/**
* [CustomExceptionClass] throws when internet is not available
* */
private class NoInternetException() : IOException() {
override val message: String
get() = "No internet available, please check your WIFi or Data connection"
}
}
*****************
object ApiConstant {
const val HEADER_CACHE_CONTROL = "Cache-Control"
const val HEADER_PRAGMA = "Pragma"
const val CONNECT_TIME_OUT = 30L
const val READ_TIME_OUT = 30L
const val WRITE_TIME_OUT = 60L
const val NETWORK_INTERCEPTOR_MAX_AGE = 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment