1
votes

I am facing with SharedPreferences problem. I would like to know how I can call SharedPreferences inside Retrofit. I mean, I have this following file :

@Module
class NetworkModule {

@Provides
internal fun provideGson(): Gson {
    return GsonBuilder().create()
}

@Provides
internal fun provideOkHttpClient(): OkHttpClient {
    return OkHttpClient.Builder().addInterceptor { chain ->
        val original = chain.request()
        val requestBuilder = original.newBuilder().addHeader("Accept", "application/json")
        val request = requestBuilder.method(original.method(), original.body()).build()
        chain.proceed(request)
    }.build()
}

@Provides
internal fun provideRetrofit(gson: Gson, okHttpClient: OkHttpClient): Retrofit {
    return Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .build()
}
}

And in my Presenter, I have this following code:

override fun getSavedToken() {
    mToken = mSharedPreferences.getString(TOKEN, TOKEN_UNAVAILABLE)
}

... 

inner class GetAccessTokenSubscriber : ResourceObserver<AccessTokenBean>() {

    override fun onNext(@NonNull accessToken: AccessTokenBean) {
        mSharedPreferences.edit().putString(TOKEN, accessToken.token).apply()
        getInformation()
    }

    override fun onError(@NonNull e: Throwable) {
        mView?.displayError()
    }

    override fun onComplete() {
        // Nothing to do
    }
}

Currently, to set the token I put the Bearer $token in my repository / service

// Repository
val newToken = "Bearer $token"
    return mService.getInfos(newToken)

// Service
fun getInfos(@Header("Authorization") token: String

I would like to know how I can put the Bearer + token inside my NetworkModule file?

Thank you for your time.

1
the module is not used to store data, modules are used only for dependency graph - coroutineDispatcher
What I have to do is to create an Interceptor right? - Tai Nguyen
is your sharedPreferences provided by dagger? - coroutineDispatcher
Singleton Provides fun provideSharedPreferences(context: Context): SharedPreferences { return PreferenceManager.getDefaultSharedPreferences(context) } inside my applicationModule - Tai Nguyen
ok super, I'm writing an answer than - coroutineDispatcher

1 Answers

2
votes

If you want to place the value on the interceptor, just call your SharedPreferences instance on the interceptor provider:

@Provides
internal fun provideOkHttpClient(sharedPrefs: SharedPrefs): OkHttpClient {
    return OkHttpClient.Builder().addInterceptor { chain ->
        val original = chain.request()
        val requestBuilder = original.newBuilder().addHeader("Accept", "application/json")
        val request = requestBuilder.method(original.method(), original.body()).build()
        chain.proceed(request)
    }.build()
}

Now dagger will look for that, but it won't find it, giving you an error. In that case, if you network module is also a singleton too just add a includes = [PreferencesModule::class], if not, you may need to set the current component dependent on the Singleton where you preferences module is located.