eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

Kotlin 1.6に変更してproguardをかけたら通信周りが死んだので直した

事象

  • アプリにログインできない

調査

  • APIcurlすると、正常に動作する(サーバーは正常動作してる)
  • Debugビルドで実行すると、正常に動作する(プログラム自体は正常である)
  • サーバーのログを確認すると、送信値のValidationに失敗している

Releaseビルドでの動作

  • APIRetrofit2 を経由でコールしている
  • JSON変換は moshi を利用している
  • このどちらかに問題が発生した可能性が高い

APIサーバーにどんな値が送られているのか

  • 送信値の直接的なログはない
    • 値のValidationに失敗した、という情報しか出してない
  • まずは手元のアプリでどんな値が実際に送信されているかLogcat

github.com

  • 結果として、snake_caseとして送信しなければならない値がcamelCaseとしてJSON化されていることがわかった
    • moshiには @Json("user_name") のようにAnnotationを付与しているので、Annotationが殺されているのがわかった
data class ExampleLogin(
   @Json("user_name")
   val userName,
)
  • 器用にsnake_caseがcamelCase化処理されるとは考えにくいので、おそらくdata classのプロパティ名がそのまま使われているのだろうと予想する

proguardルールを変更した

  • どうやってもダメ
  • 全部のclassやinterfaceをkeepしてもAnnotationが剥がれてしまう

Annotationを付け替えた

  • filedに付与すると、proguardを通してもAnnotationが生きている
  • なんとなくだが、Proguardの最適化によってField/Methodの扱いが変わってしまったように思う
  • ただし、このままだとProguard前のデバッグで不正になる
data class ExampleLogin(
   @JvmField
   @field:Json("user_name")
   val userName,
)

Annotationをさらにつけた

  • モリモリ全部盛りで、FieldとMethodに付与した。
  • これでDebugもReleaseもOK
  • 変換用Classは全部Generatorが吐き出しているので、テンプレートだけ対応してあげてヨシ.
data class ExampleLogin(
   @JvmField
   @field:Json("user_name")
   @Json("user_name")
   val userName,
)

Kotlin 1.6はなかなか色々大変だったが、これでひと段落のはず