7

I recently got to know about Koin. I was trying to migrate my current project from Dagger to Koin. In doing so, I faced an issue with injecting sharedPreferences and sharedPreferences editor in the activities.

Following is the code I used in Dagger to inject sharedPreferences and sharedPreferences editor ->

    @Provides
    @AppScope
    fun getSharedPreferences(context: Context): SharedPreferences =
            context.getSharedPreferences("default", Context.MODE_PRIVATE)

    @SuppressLint("CommitPrefEdits")
    @Provides
    @AppScope
    fun getSharedPrefrencesEditor(context: Context): SharedPreferences.Editor =
            getSharedPreferences(context).edit()

I tried to convert the above mentioned code to Koin like this ->

val appModule = module {

    val ctx by lazy{ androidApplication() }

    single {
        ctx.getSharedPreferences("default", Context.MODE_PRIVATE)
    }

    single {
        getSharedPreferences(ctx).edit()
    }
}

I also tried to implement it this way ->

val appModule = module {

        single {
            androidApplication().getSharedPreferences("default", Context.MODE_PRIVATE)
        }

        single {
            getSharedPreferences(androidApplication()).edit()
        }
    }

Now I inject the dependencies in my activity like this ->

val sharedPreferences: SharedPreferences by inject()

val sharedPreferencesEditor: SharedPreferences.Editor by inject()

But as soon as I launch my app and try to use them, I am not able to read or write anything to the preferences.

I am a bit confused as to what is wrong with the code. Kindly help me figure this out.

Annsh Singh
  • 435
  • 5
  • 12

1 Answers1

11

I figured out a way to handle this. Hope this helps someone looking for the same issue.

Here is the solution to the problem:

The koin module definition will be like this ->

 val appModule = module {

    single{
        getSharedPrefs(androidApplication())
    }

    single<SharedPreferences.Editor> {
        getSharedPrefs(androidApplication()).edit()
    }
 }

fun getSharedPrefs(androidApplication: Application): SharedPreferences{
    return  androidApplication.getSharedPreferences("default",  android.content.Context.MODE_PRIVATE)
}

Just to be clear that the above code is in the file modules.kt

Now you can easily inject the created instances like ->

private val sharedPreferences: SharedPreferences by inject()

private val sharedPreferencesEditor: SharedPreferences.Editor by inject()

Make sure the above instances are val instead of var otherwise the inject() method will not work as this is lazy injection.

Annsh Singh
  • 435
  • 5
  • 12
  • Is hardcoding the word "default" actually gives the default SharedPreference? – Richard Miller Dec 04 '19 at 13:07
  • 1
    i am getting error of `Caused by: org.koin.core.error.NoBeanDefFoundException: No definition found for 'android.content.SharedPreferences' has been found. Check your module definitions` – Shvet Jul 29 '20 at 11:08
  • @Shvet have you found solution for this? – Noorul Jun 20 '22 at 14:05
  • @Noorul Don't remember much now, at that time i was also learning koin implementation and it been 2 years. i have to go and find old code. – Shvet Jun 21 '22 at 10:46
  • https://stackoverflow.com/questions/72688110/no-bean-definition-found-exception – Noorul Jun 21 '22 at 11:31
  • its been 21 hours. still I didn't get answer. – Noorul Jun 21 '22 at 11:31
  • I think it is better to create a function to get the editor of the SharedPreferences like this : `fun getSharedPrefsEditor(sharedPreferences: SharedPreferences):SharedPreferences.Editor = sharedPreferences.edit()` and get it like this: `single { getSharedPrefsEditor(get()) }` your code create two SharedPreferences object and I think it is wrong. – Maryam Memarzadeh Jan 21 '23 at 06:43