Koin + Retrofit добавляет заголовок во время выполнения

У меня есть проект на основе монет и модернизации в архитектуре MVVM. Я хочу распечатать данные с помощью «viewmodel» и добавить значение «токена» в заголовок во время выполнения после регистрации этого проекта. Но я не смог предоставить структуру контекста, необходимую для получения маркера, который я сохранил в SharedPreferences. Как я могу справиться с этим в самой чистой форме?

 fun createNetworkClient(baseUrl: String) =
        retrofitClient(baseUrl, httpClient())


    private fun httpClient(): OkHttpClient {

        val httpLoggingInterceptor = HttpLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT)
        val clientBuilder = OkHttpClient.Builder()
        if (BuildConfig.DEBUG) {
            httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
            clientBuilder.addInterceptor(httpLoggingInterceptor)
        }
        clientBuilder.addInterceptor { chain ->
            val newRequest = chain.request().newBuilder()
                .addHeader( //I can't get token because there is no context here.
                    "Authorization", "Bearer ${PreferencesHelper.getInstance(context).token.toString()}"
                )
                .build()
            chain.proceed(newRequest)
        }



        clientBuilder.readTimeout(120, TimeUnit.SECONDS)
        clientBuilder.writeTimeout(120, TimeUnit.SECONDS)
        return clientBuilder.build()
    }

    private fun retrofitClient(baseUrl: String, httpClient: OkHttpClient): Retrofit =
        Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(httpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()

AppModule

val appModule = module {
    single {
        androidApplication().getSharedPreferences("PREFERENCES", android.content.Context.MODE_PRIVATE)
    }
    single { createNetworkClient(BuildConfig.BASE_URL) }
    single { (get() as Retrofit).create(Api::class.java) } 
    viewModel {
        ContactViewModel(get())
    }
}

Моя контактная активность

 private val contactList: ContactViewModel  by viewModel()
    override fun onCreate(savedInstanceState: Bundle?) {
        viewModel = contactList

        super.onCreate(savedInstanceState)
        binding.adapter = ContactAdapter(this)
        binding.layoutManager = LinearLayoutManager(this)

        contactList.getContactList()

        contactList.contactListLiveData.observe(this, Observer { list ->
            if (list != null)
                binding.adapter?.update(list)
        })
    }

person Hasan Kucuk    schedule 28.06.2019    source источник


Ответы (1)


Вы можете создать модуль Koin для предоставления общих настроек:

val sharedPreferencesModule = module {

   single {
      androidApplication().getSharedPreferences("PREFERENCES",  android.content.Context.MODE_PRIVATE)
   }
}

А затем внедрить его с помощью Koin в класс, который генерирует клиент Retrofit.

ИЗМЕНИТЬ

Вам нужно изменить сигнатуру метода createNetworkClient:

fun createNetworkClient(baseUrl: String, preferences: SharedPreferences)

А затем введите его с помощью Koin:

val appModule = module {
    single {
        androidApplication().getSharedPreferences("PREFERENCES", android.content.Context.MODE_PRIVATE)
    }
    single { createNetworkClient(BuildConfig.BASE_URL, get()) }

    ...
}

Затем вы получите общие настройки, внедренные в метод createNetworkClient, и вам просто нужно реализовать логику для извлечения токена из общих настроек.

person Jaime Suarez    schedule 28.06.2019
comment
как мне его впрыснуть. Я немного новичок в этом. - person Hasan Kucuk; 28.06.2019
comment
Можете ли вы опубликовать свой полный класс Retrofit и модули koin? - person Jaime Suarez; 28.06.2019