Search code examples
kotlin-multiplatform

Using context in KMM shared library (Manually)


I am building a common library module in KMM that requires android application context.

How can I pass it to common module manually?

I have seen answers using androidx.startup.InitializationProvider which requires separate dependency.

I don't want any dependency.


Solution

  • Found a good solution using expect/actual mechanism of object.

    1. Create an expect object in commonMain
    expect object AppContext
    
    1. Create actual object in androidMain
    import android.content.Context
    import java.lang.ref.WeakReference
    
    actual object AppContext {
    
        private var value: WeakReference<Context?>? = null
    
        fun set(context: Context) {
            value = WeakReference(context)
        }
    
        internal fun get(): Context? {
            return value?.get()
        }
    
    }
    
    1. Leave iOS AppContext empty as we don't need context there
    actual object AppContext
    
    1. Create another class in commonMain
    class MyLibConfig(
        val appContext: AppContext,
        val isTestDevice: Boolean = false,
        val isLogsEnabled: Boolean = false,
    )
    
    1. Create your commonMain public API object
    object MyLib {
        fun initialize(config: MyLibConfig) {
            val commonContext = config.appContext
        }
    }
    
    1. Pass this context to your native platform specific methods as argument. For example
    override fun getMyLibDatabase(appContext: AppContext): SqlDriver {
            return AndroidSqliteDriver(
                my_lib_db.Schema,
                appContext.get()!!,
                "my_lib_db.sqlite"
            )
        }
    
    1. Initialize your library from ViewModel or Application class. Much more clear way
    MyLib.initialize(
                MyLibConfig(
                    appContext = AppContext.apply { set(application.applicationContext) },
                    isTestDevice = true,
                    isLogsEnabled = true,
                )
            )