diff --git a/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt index 0fe2951..67e12d9 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt @@ -23,7 +23,7 @@ class AuthDataSourceImpl @Inject constructor( override suspend fun authenticate(username: String, password: String): String { Timber.v("authenticate() called with: username = $username, password = $password") - val authService = authServiceFactory.provideService() + val authService = authServiceFactory.provideService(needAuth = false) val response = sendRequest(authService, username, password) val accessToken = parseToken(response) Timber.v("authenticate() returned: $accessToken") diff --git a/app/src/main/java/gq/kirmanak/mealient/data/network/OkHttpBuilder.kt b/app/src/main/java/gq/kirmanak/mealient/data/network/OkHttpBuilder.kt deleted file mode 100644 index 325f96f..0000000 --- a/app/src/main/java/gq/kirmanak/mealient/data/network/OkHttpBuilder.kt +++ /dev/null @@ -1,21 +0,0 @@ -package gq.kirmanak.mealient.data.network - -import okhttp3.Interceptor -import okhttp3.OkHttpClient -import timber.log.Timber -import javax.inject.Inject - -class OkHttpBuilder @Inject constructor( - // Use @JvmSuppressWildcards because otherwise dagger can't inject it (https://stackoverflow.com/a/43149382) - private val authenticationInterceptor: AuthenticationInterceptor, - private val interceptors: Set<@JvmSuppressWildcards Interceptor>, -) { - - fun buildOkHttp(): OkHttpClient { - Timber.v("buildOkHttp() called") - return OkHttpClient.Builder().apply { - addInterceptor(authenticationInterceptor) - for (interceptor in interceptors) addNetworkInterceptor(interceptor) - }.build() - } -} diff --git a/app/src/main/java/gq/kirmanak/mealient/data/network/RetrofitBuilder.kt b/app/src/main/java/gq/kirmanak/mealient/data/network/RetrofitBuilder.kt index 2f6cb3e..fc61647 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/network/RetrofitBuilder.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/network/RetrofitBuilder.kt @@ -1,6 +1,8 @@ package gq.kirmanak.mealient.data.network import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory +import gq.kirmanak.mealient.di.AUTH_OK_HTTP +import gq.kirmanak.mealient.di.NO_AUTH_OK_HTTP import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import okhttp3.MediaType.Companion.toMediaType @@ -8,22 +10,25 @@ import okhttp3.OkHttpClient import retrofit2.Retrofit import timber.log.Timber import javax.inject.Inject +import javax.inject.Named import javax.inject.Singleton @Singleton class RetrofitBuilder @Inject constructor( - private val okHttpClient: OkHttpClient, + @Named(AUTH_OK_HTTP) private val authOkHttpClient: OkHttpClient, + @Named(NO_AUTH_OK_HTTP) private val noAuthOkHttpClient: OkHttpClient, private val json: Json ) { @OptIn(ExperimentalSerializationApi::class) - fun buildRetrofit(baseUrl: String): Retrofit { + fun buildRetrofit(baseUrl: String, needAuth: Boolean): Retrofit { Timber.v("buildRetrofit() called with: baseUrl = $baseUrl") val contentType = "application/json".toMediaType() val converterFactory = json.asConverterFactory(contentType) + val client = if (needAuth) authOkHttpClient else noAuthOkHttpClient return Retrofit.Builder() .baseUrl(baseUrl) - .client(okHttpClient) + .client(client) .addConverterFactory(converterFactory) .build() } diff --git a/app/src/main/java/gq/kirmanak/mealient/data/network/RetrofitServiceFactory.kt b/app/src/main/java/gq/kirmanak/mealient/data/network/RetrofitServiceFactory.kt index 7a7ea95..d112685 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/network/RetrofitServiceFactory.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/network/RetrofitServiceFactory.kt @@ -13,21 +13,28 @@ class RetrofitServiceFactory( private val baseURLStorage: BaseURLStorage, ) : ServiceFactory { - private val cache: MutableMap = mutableMapOf() + private val cache: MutableMap = mutableMapOf() - override suspend fun provideService(baseUrl: String?): T = runCatchingExceptCancel { + override suspend fun provideService( + baseUrl: String?, + needAuth: Boolean, + ): T = runCatchingExceptCancel { Timber.v("provideService() called with: baseUrl = $baseUrl, class = ${serviceClass.simpleName}") val url = baseUrl ?: baseURLStorage.requireBaseURL() - synchronized(cache) { cache[url] ?: createService(url, serviceClass) } + val params = ServiceParams(url, needAuth) + synchronized(cache) { cache[params] ?: createService(params, serviceClass) } }.getOrElse { Timber.e(it, "provideService: can't provide service for $baseUrl") throw NetworkError.MalformedUrl(it) } - private fun createService(url: String, serviceClass: Class): T { - Timber.v("createService() called with: url = $url, serviceClass = ${serviceClass.simpleName}") - val service = retrofitBuilder.buildRetrofit(url).create(serviceClass) - cache[url] = service + private fun createService(serviceParams: ServiceParams, serviceClass: Class): T { + Timber.v("createService() called with: serviceParams = $serviceParams, serviceClass = ${serviceClass.simpleName}") + val (url, needAuth) = serviceParams + val service = retrofitBuilder.buildRetrofit(url, needAuth).create(serviceClass) + cache[serviceParams] = service return service } + + data class ServiceParams(val baseUrl: String, val needAuth: Boolean) } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/data/network/ServiceFactory.kt b/app/src/main/java/gq/kirmanak/mealient/data/network/ServiceFactory.kt index e46c2a8..0ab4a78 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/network/ServiceFactory.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/network/ServiceFactory.kt @@ -2,5 +2,5 @@ package gq.kirmanak.mealient.data.network interface ServiceFactory { - suspend fun provideService(baseUrl: String? = null): T + suspend fun provideService(baseUrl: String? = null, needAuth: Boolean = true): T } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/di/NetworkModule.kt b/app/src/main/java/gq/kirmanak/mealient/di/NetworkModule.kt index 80de298..0a49c38 100644 --- a/app/src/main/java/gq/kirmanak/mealient/di/NetworkModule.kt +++ b/app/src/main/java/gq/kirmanak/mealient/di/NetworkModule.kt @@ -4,19 +4,41 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import gq.kirmanak.mealient.data.network.OkHttpBuilder +import gq.kirmanak.mealient.data.network.AuthenticationInterceptor import kotlinx.serialization.json.Json +import okhttp3.Interceptor import okhttp3.OkHttpClient +import javax.inject.Named import javax.inject.Singleton +const val AUTH_OK_HTTP = "auth" +const val NO_AUTH_OK_HTTP = "noauth" + @Module @InstallIn(SingletonComponent::class) object NetworkModule { @Provides @Singleton - fun createOkHttp(okHttpBuilder: OkHttpBuilder): OkHttpClient = - okHttpBuilder.buildOkHttp() + @Named(AUTH_OK_HTTP) + fun createAuthOkHttp( + // Use @JvmSuppressWildcards because otherwise dagger can't inject it (https://stackoverflow.com/a/43149382) + interceptors: Set<@JvmSuppressWildcards Interceptor>, + authenticationInterceptor: AuthenticationInterceptor, + ): OkHttpClient = OkHttpClient.Builder() + .addInterceptor(authenticationInterceptor) + .apply { for (interceptor in interceptors) addNetworkInterceptor(interceptor) } + .build() + + @Provides + @Singleton + @Named(NO_AUTH_OK_HTTP) + fun createNoAuthOkHttp( + // Use @JvmSuppressWildcards because otherwise dagger can't inject it (https://stackoverflow.com/a/43149382) + interceptors: Set<@JvmSuppressWildcards Interceptor>, + ): OkHttpClient = OkHttpClient.Builder() + .apply { for (interceptor in interceptors) addNetworkInterceptor(interceptor) } + .build() @Provides @Singleton diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/picasso/PicassoBuilder.kt b/app/src/main/java/gq/kirmanak/mealient/ui/picasso/PicassoBuilder.kt index 31e885f..a2cea53 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/picasso/PicassoBuilder.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/picasso/PicassoBuilder.kt @@ -5,15 +5,17 @@ import com.squareup.picasso.OkHttp3Downloader import com.squareup.picasso.Picasso import dagger.hilt.android.qualifiers.ApplicationContext import gq.kirmanak.mealient.BuildConfig +import gq.kirmanak.mealient.di.AUTH_OK_HTTP import okhttp3.OkHttpClient import timber.log.Timber import javax.inject.Inject +import javax.inject.Named import javax.inject.Singleton @Singleton class PicassoBuilder @Inject constructor( @ApplicationContext private val context: Context, - private val okHttpClient: OkHttpClient + @Named(AUTH_OK_HTTP) private val okHttpClient: OkHttpClient ) { fun buildPicasso(): Picasso {