0

While trying to use the WeatherApp Sample, I am not understanding how I would change it so that each widget did infact use it's own datastore, rather than a shared one.

My understanding is that datastore as it is in the sample below, are saved to the DATA_STORE_FILENAME, and thus each widget overwrites the last, so all widgets essentially would have the same state.

The comment says to create a store using the provided fileKey but I don't know how I could get the fileKey before creating the datastore?

/**
 * Provides our own definition of "Glance state" using Kotlin serialization.
 */
object WeatherInfoStateDefinition : GlanceStateDefinition<WeatherInfo> {

    private const val DATA_STORE_FILENAME = "weatherInfo"

    /**
     * Use the same file name regardless of the widget instance to share data between them
     *
     * If you need different state/data for each instance, create a store using the provided fileKey
     */
    private val Context.datastore by dataStore(DATA_STORE_FILENAME, WeatherInfoSerializer)

    override suspend fun getDataStore(context: Context, fileKey: String): DataStore<WeatherInfo> {
        return context.datastore
    }

    override fun getLocation(context: Context, fileKey: String): File {
        return context.dataStoreFile(fileKey)
    }

My best guess was to replace all instances of DATA_STORE_FILENAME with the fileKey, but for the creation of the datastore, it does not work, as the key has not yet been created?

private val Context.datastore by dataStore(fileKey, WeatherInfoSerializer)

Could someone please provide some clues as to how the fileKey is supposed to be used to create a unique datastore per widget?

ddxv
  • 23
  • 5

1 Answers1

0

I was able to get help from the Kotlin slack group which has a Glance channel. The change below is quite simple and is able to be added directly to the example WeatherApp and only changes a line or two in the worker (so that each widget displays different information for testing purposes).

// Rename DATA_STORE_FILENAME for clarity
 private const val DATA_STORE_FILENAME_PREFIX = "weatherInfo_"

// The below line can be removed as it is no longer needed
//private val Context.datastore by dataStore(DATA_STORE_FILENAME, WeatherInfoSerializer)


// getDataStore now uses DataStoreFactory
    override suspend fun getDataStore(context: Context, fileKey: String) = DataStoreFactory.create(
        serializer = WeatherInfoSerializer,
        produceFile = { getLocation(context, fileKey) }
    )

    override fun getLocation(context: Context, fileKey: String) =
        context.dataStoreFile(DATA_STORE_FILENAME_PREFIX + fileKey.lowercase())

And that's it. Now data store in the example WeatherApp will create a file per widget.

ddxv
  • 23
  • 5