Custom Storage
The SDK persists two internal keys: a first-launch flag (Detour_firstEntranceFlag) and an analytics device identifier (Detour_deviceId). Left unset, DetourConfig.storage is null and the SDK falls back to its own SharedPreferences-based store. To use encrypted storage, DataStore or another persistence layer, pass a DetourStorage implementation instead.
Storage interface
Section titled “Storage interface”interface DetourStorage { suspend fun getItem(key: String): String? suspend fun setItem(key: String, value: String) suspend fun removeItem(key: String) { }}Examples
Section titled “Examples”The adapter below wraps EncryptedSharedPreferences. Any class that implements DetourStorage works, so use it as a starting point for DataStore or another persistence layer.
EncryptedSharedPreferences
Section titled “EncryptedSharedPreferences”import android.content.Contextimport androidx.security.crypto.EncryptedSharedPreferencesimport androidx.security.crypto.MasterKeyimport com.swmansion.detour.storage.DetourStorageimport kotlinx.coroutines.Dispatchersimport kotlinx.coroutines.withContext
class EncryptedStorageProvider(context: Context) : DetourStorage { private val masterKey = MasterKey.Builder(context) .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) .build()
private val prefs = EncryptedSharedPreferences.create( context, "DetourSecureStorage", masterKey, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM )
override suspend fun getItem(key: String): String? = withContext(Dispatchers.IO) { prefs.getString(key, null) }
override suspend fun setItem(key: String, value: String) = withContext(Dispatchers.IO) { prefs.edit().putString(key, value).apply() }}val config = DetourConfig( apiKey = BuildConfig.DETOUR_API_KEY, appId = BuildConfig.DETOUR_APP_ID, storage = EncryptedStorageProvider(this))