From 910ed4eebaa7a91ff9d045034b54501cf215d262 Mon Sep 17 00:00:00 2001 From: Bradley Duck Date: Wed, 10 Jun 2026 08:55:11 +0100 Subject: [PATCH] Document R8 / full-mode minification safety in README Add an R8 / ProGuard / Minification section explaining that PrefsHelper needs no consumer keep rules: preference keys are explicit string args, never derived from property names via reflection, so renaming/merging is safe. Enum values are stored by Enum.name, preserved by R8's default Android rules. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 12e7c5b..0b34bdc 100644 --- a/README.md +++ b/README.md @@ -92,3 +92,9 @@ Both `BasePrefsHelper` and `BaseDataStoreHelper` support `String`, `Int`, `Long` - `BaseDataStoreHelper` supports `Double`. Each type exposes a non-nullable delegate `*Pref(key, defaultValue)` and a nullable delegate `*Pref(key)` (assigning `null` clears the stored value on DataStore, or stores the sentinel on SharedPreferences for temporal types). `BaseDataStoreHelper` additionally exposes matching `*PrefFlow` accessors for reactive reads. + +## R8 / ProGuard / Minification + +PrefsHelper is fully compatible with R8 (including full mode) and requires **no consumer ProGuard rules** (the shipped `consumer-rules.pro` is intentionally empty). Preference keys are always explicit string arguments you pass to the `*Pref(...)` delegates — they are **never** derived from Kotlin property names via reflection. R8 is free to rename, merge, and repackage your `BasePrefsHelper`/`BaseDataStoreHelper` subclasses and their properties without changing any persisted key. Enum values are stored by `Enum.name` (preserved by R8's default Android rules), so enum prefs survive obfuscation. + +The one thing to keep in mind lives in *consumer* code, not the library: pass real string literals as keys. Since keys are explicit strings here, the classic prefs-library footgun (key derived from a renamed identifier) doesn't apply.