それがいいことの序章です

楽しいことならいっぱい夢見ることならめいっぱい

KotlinでGsonでStringをBooleanにする

やったこと

AndroidでRetrofit + Gsonを使っているときのおはなし。
APIレスポンスにStringで"0"、"1"が返ってくる場面に出くわして
これをBooleanとして扱いたくってTypeAdapterを使ったよ。

なにが起きたか

{
    "is_success": "1"
}

みたいなやつをBooleanで扱うぞと思って

data class Response(
    @SerializedName("is_success")
    val isSuccess: Boolean
)

というふうにしてたら全部trueになった。全てが正になった困った。

どうやったか

パッと思いついたのはコンバータクラス作って

// レスポンスはStringで受ける
// data class Response(
//     @SerializedName("is_success")
//     val isSuccess: String
// )

object ResponseConverter {
  fun convert(res: Response) = Item(isSuccess = res.isSuccess == "1")
}

fun Response.convert() = ResponseConverter.convert(this)

みたいにするのだけど、毎回するのアレだよな〜と思って調べたら
TypeAdapterなるものを知った。詳しくは説明しないけど便利。

ということで

class IntToBooleanTypeAdapter : TypeAdapter<Boolean>() {
    override fun write(out: JsonWriter, value: Boolean?) {
        if (value == null) {
            out.nullValue()
            return
        }

        out.value(if (value) 1 else 0)
    }

    override fun read(`in`: JsonReader): Boolean {
        if (`in`.peek() == null) return false
        return `in`.nextInt() == 1
    }
}

というふうにしてあげて、レスポンスを

data class Response(
    @SerializedName("is_success") @JsonAdapter(IntToBooleanTypeAdapter::class)
    val isSuccess: Boolean
)

のようにしてあげることで、無事変換された!!

おわりに

Gsonがどのようにうまいこと変換してくれるかまで
調べるのに手が回ってないので時間ができたら調べる。

Gsonなのか、Kotlinの型の問題なのかわすれちゃった。。
Javaのときはできてたような…できてなかったような…

調べたら追記するかも。明日はDroidKaigi。