Challenge 1: A Keep Rule for a Reflection-Dependent Class — Solution data class ApiUser(val id: Int, val name: String) // proguard-rules.pro -keep class com.philip.myapp.data.ApiUser { *; } // What would break without this rule, and how it would likely manifest: // // R8 would rename ApiUser's class name and its "id"/"name" properties to // short, arbitrary names (e.g. class "a" with fields "b" and "c") as // part of its normal obfuscation pass. Moshi's JSON deserialization // relies on matching JSON keys ("id", "name" from the actual API // response) against the CLASS'S ACTUAL FIELD NAMES via reflection — once // those field names are renamed by R8, that matching fails silently for // each field. In practice this typically manifests as ApiUser instances // where every property is null or a default value (0, "") even though // the network call itself succeeded and returned correct JSON — a // confusing bug specifically because it only appears in release builds // (where minification is on) and never in debug builds, and there's no // crash or obvious error message pointing at the real cause. Notes: - { *; } inside the keep rule means "keep every member" (all fields and methods), not just the class name itself — a keep rule on just the class name without { *; } would still allow R8 to rename the properties inside it, which is exactly the part JSON deserialization actually depends on. - com.philip.myapp.data.** (using a wildcard, as shown in the chapter's broader example) is a common practical shortcut — keeping every class in a dedicated "data" package used for API/database models — rather than writing one -keep line per individual data class. - This class of bug is exactly why the chapter's warning box stresses testing an actual release build (isMinifyEnabled = true) before shipping, not just relying on debug-build testing.