CommonMain 中的 Kotlin 多平台移动上下文

问题描述 投票:0回答:2

CommonMain 中的 Kotlin 多平台移动上下文

嗨,我目前正在探索 KMM 开发,但我陷入了 Context 部分。

我想创建一个类,它将处理安全数据存储。我为 iOS 和 Android 创建了一个 expect class Manager 和两个 actual class Manager。对于 Android 部分,框架和所有其他可用工具都需要 Context

我想使用这个 Manager 来存储和读取 CommonMain 中的值。但从项目的共享部分来看,没有提供 Context

我如何实现这一目标?

这是代码:

expect class TokenStore(context: Any) {
    fun getToken(): String?
    fun saveToken(token: String)
}
import com.liftric.kvault.KVault



actual class TokenStore actual constructor(context: Any) {
    private val store = KVault("com.example.keystoreexample")
    actual fun getToken(): String? {
        val token = store.string("ACCOUNT_TOKEN")
        return if (token != null) {
            println("✅ The token was found.\nThe value is: $token")
            token
        } else {
            println("❌ There is no token in the Token Store.")
            null
        }
    }

    actual fun saveToken(token: String) {
        if (token == "") println("⚠️ No token was provided.\nWatch out for this one.")
        if (store.existsObject("ACCOUNT_TOKEN")) {
            val existingObject = store.string("ACCOUNT_TOKEN")
            print("ℹ️ Object is already in the Token Store.\nThe token value is: $existingObject")
            if (store.clear()) {
                println("✅ All values in Token Store were removed.")
            } else {
                println("❌ There was an issue removing objects from the Token Store.")
            }
        } else {
            println("ℹ️ Object under this key is not stored in a database yet.")
        }
        if (store.set("ACCOUNT_TOKEN", token)) {
            println("✅ The token was added to the Token Store.")
        } else {
            println("❌ There was an issue inserting token to the Token Store.")
        }
    }
}
import android.content.Context
import com.liftric.kvault.KVault

actual class TokenStore actual constructor(private val context: Any) {
    private val store = KVault(context as Context)
    actual fun getToken(): String? {
        val token = store.string("ACCOUNT_TOKEN")
        return if (token != null) {
            println("✅ The token was found.\nThe value is: $token")
            token
        } else {
            println("❌ There is no token in the Token Store.")
            null
        }
    }

    actual fun saveToken(token: String) {
        if (token == "") println("⚠️ No token was provided.\nWatch out for this one.")
        if (store.existsObject("ACCOUNT_TOKEN")) {
            val existingObject = store.string("ACCOUNT_TOKEN")
            print("ℹ️ Object is already in the Token Store.\nThe token value is: $existingObject")
            if (store.clear()) {
                println("✅ All values in Token Store were removed.")
            } else {
                println("❌ There was an issue removing objects from the Token Store.")
            }
        } else {
            println("ℹ️ Object under this key is not stored in a database yet.")
        }
        if (store.set("ACCOUNT_TOKEN", token)) {
            println("✅ The token was added to the Token Store.")
        } else {
            println("❌ There was an issue inserting token to the Token Store.")
        }
    }
}

我想在这里使用它例如:

package com.example.keystoresample

// CommonMain
import TokenStore

class Greeting {
    private val platform: Platform = getPlatform()
    private val token = TokenStore(context).getToken() // Where can I get it?

    fun greet(): String {
        return "Hello, ${platform.name}!\nThe token value is:\n$token"
    }
}

我想我已经尝试了很多。

android ios kotlin kotlin-multiplatform multiplatform
2个回答
1
投票

是否需要

Context
必须转移到依赖于平台的实现。 您可能只需要KVault


0
投票

这个答案可能为时已晚,但如果其他人面临同样的问题,我想将其留在这里。

您可以使用

androidx.startup
库来获取应用程序上下文的实例。您可以将其存储在变量中并在任何您想要的地方使用它。应用程序上下文存在于整个应用程序生命周期中,因此不存在泄漏上下文的问题。它类似于使用柄在视图模型上注入应用程序上下文。

注意:活动提供的上下文和应用程序上下文之间存在差异。

  1. 添加
    androidx.startup
    对您的
    androidMain
    源集的依赖。

   val androidMain by getting {
       dependencies {
           implementation("androidx.startup:startup-runtime:1.1.1")
        }
   }

  1. 为上下文创建一个初始化类

    import android.content.Context
    import androidx.startup.Initializer
    
    lateinit var applicationContext: Context
    
    class ApplicationContextInitializer : Initializer<Context> {
      override fun create(context: Context): Context = context.also {
        applicationContext = it.applicationContext
      }
    
      override fun dependencies(): List<Class<out Initializer<*>>> = emptyList()
    }

  1. 在清单上使用正确的元数据注册
    InitializationProvider

    <application>
        <provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:exported="false"
            tools:node="merge">

            <!-- Replace com.example with actual package name -->
            <meta-data
                android:name="com.example.ApplicationContextInitializer"
                android:value="androidx.startup" />
        </provider>
    </application>

仅此而已。

© www.soinside.com 2019 - 2024. All rights reserved.