微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在视图模型中从 DataStore 首选项如 Flow中获取值

如何解决如何在视图模型中从 DataStore 首选项如 Flow中获取值

我有一个问题,我可以通过 SharedPreferences 解决。 但现在我要迁移到 kotlin 和 DataStore。

我遇到了这个问题。

我有一个字符串值存储在共享首选项中,以及其他键值对中。 此字符串是一个 URL,用于在 Retrofit 调用的 baseUrl 参数中使用。

我的问题是,当我在 viewmodel 中运行 Fragment 时,检索值的正确方法是什么。

这是我的代码的一部分:

@Singleton
class PreferencesManager @Inject constructor(
    @ApplicationContext context: Context,anioDao: AnioDao
) {

   val baseUrlFlow = dataStore.data
        .catch { exception ->
            if (exception is IOException) {
                Log.e(TAG,"Error reading preferences: ",exception)
                emit(emptyPreferences())
            } else {
                throw exception
            }
        }
        .map {
            it[PreferencesKeys.BASER_URL] ?: "http://192.168.2.109:1337"
        }

}

然后在 viewmodel 类中

class Ensayosviewmodel @viewmodelInject constructor(
    private val ensayoRepository: EnsayoRepository,private val anioRepository: AnioRepository,private val localidadRepository: LocalidadRepository,private val epocaRepository: EpocaRepository,private val preferencesManager: PreferencesManager,private val agrotrackerApi: AgrotrackerApi,@Assisted private val state: SavedStateHandle

) :
    viewmodel() {

...

//Base Url
val baseUrlFlow = preferencesManager.baseUrlFlow
private val _baseUrl = mutablelivedata<String>()
private fun getBaseUrl() {

    viewmodelScope.launch {
        baseUrlFlow.flowOn(dispatchers.IO).collect{
            _baseUrl.value = it
        }
    }
}

  ...

fun fetchEsayosFromAT() {

 //This is where I want to get value of the base_url key.

}

但是好像很复杂,对于一个简单的任务...

我错过了什么?我真的迷路了。

最好的问候

解决方法

获取共享首选项数据的一种方法是将 Flow 转换为 LiveData。它工作正常,但很可能会被 StateFlow/SharedFlow 替换为首选方法。

  1. 在返回 Flow 的 Preference 存储库中创建一个方法

    <div class="raven-image-fit">Box 1</div>
    <div class="raven-image-fit">Box 2</div>
  2. 在您的 ViewModel 中初始化 LiveData,如下所示(您可以从 ViewModel 或 Fragment 访问它)

    override fun getBaseUrlPreferencesFlow(): Flow<String> = context.dataStore.data
    .catch { exception ->
        if (exception is IOException) {
            Log.e(TAG,"Error reading preferences: ",exception)
            emit(emptyPreferences())
        } else {
            throw exception
        }
    }
    .map { pref ->
       it[PreferencesKeys.BASER_URL] ?: "http://192.168.2.109:1337"
    }
    
  3. (可选)在 ViewModel - 添加辅助方法来处理基本 url

    val baseUrlLiveData: LiveData<String> = 
    yourInjectedRepository.getBaseUrlPreferencesFlow().asLiveData()
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。