2

I am writing an application with Kotlin and Retrofit 2. As I use proguard, I follow the rules here:

https://github.com/krschultz/android-proguard-snippets/blob/master/libraries/proguard-square-retrofit2.pro

Besides I also need to proguard my models too, as stated in https://stackoverflow.com/a/41136007/3286489

It works fine if I have my models in a package, and I have -keep class com.elyeproj.wikisearchcount.model.** { *; }

package com.elyeproj.wikisearchcount.model

object Model {
    data class Result(val query: Query)
    data class Query(val searchinfo: SearchInfo)
    data class SearchInfo(val totalhits: Int)
}

However, if I keep my Models in the base package as the code below, but I don't want to keep the entire package i.e. -keep class com.elyeproj.wikisearchcount.** { *; }, since this defeat the purpose of proguard

package com.elyeproj.wikisearchcount

object Model {
    data class Result(val query: Query)
    data class Query(val searchinfo: SearchInfo)
    data class SearchInfo(val totalhits: Int)
}

How could I keep my model classes?

I tried -keep class com.elyeproj.wikisearchcount.Model.** { *; }, but it doesn't work.

Janusz
  • 187,060
  • 113
  • 301
  • 369
Elye
  • 53,639
  • 54
  • 212
  • 474

3 Answers3

9

Why don't you use the annotation @SerializedName and then you don't have to worry about the obfuscation? You could use the following code:

object Model {
    data class Result(@SerializedName("query") val query: Query)
    data class Query(@SerializedName("searchInfo") val searchinfo: SearchInfo)
    data class SearchInfo(@SerializedName("totalhits") val totalhits: Int)
}
Jc Miñarro
  • 1,391
  • 10
  • 18
4

After exploring further, I found the answer

-keep class com.elyeproj.wikisearchcount.Model** { *; }
Elye
  • 53,639
  • 54
  • 212
  • 474
0

For people still having this issue... I've had this issue both with Volley + Moshi, and now Retrofit + Gson, though neither was the problem. The real problen is that your model gets obfuscated, which is what you want to prevent. To do so, you have 3 options:

@SerializedName annotation
As Jc Miñarro suggested, annotate your parameters with @SerializedName, like so:

data class YourModel(
    @SerializedName("param1") val param1: String
)


@Keep annotation
Another option, is to use the @Keep annotation when defining your model:

@Keep
data class YourModel(...)


Proguard rule
Last option is to define your "ignore" rules in your proguard-rules.pro file. e.g. to ignore all models in your /api/models/:

-keep class com.yourapp.api.models.** { *; }
Ricardo Yubal
  • 374
  • 3
  • 8