1. soranakk

    No comment

    soranakk
Changes in body
Source | HTML | Preview
@@ -1,137 +1,139 @@
-# Moshi-adapters
+# Moshi-adaptersの紹介
Moshi-adaptersはMoshiのアドオンライブラリです。
+Moshi公式からリリースされています。
+まずはMoshiって何?って方のために、簡単にMoshiの紹介から。
# Moshi
MoshiはKotlinでJsonを扱うライブラリです。
標準的なデータ型とjsonの相互変換をサポートしています。
* int, float, charなどのプリミティブ型および、それらのオブジェクト型(Integer, Float, Character)
* Arrays, List, Mapなど
* String
* Enum
# Moshi-codegen
Moshiでサポートしていない型(自作Classなど)を扱うときにはAdapterを作成する必要があります。
ですが、それをannotation processorで生成してくれるライブラリがMoshi-codegenです。
Moshi-codegenはMoshi公式からリリースされています。
以下のように変換したいクラスにアノテーションをつけることでAdapterが自動生成されます。
これはKotlinのdata classも対象にできます。
```Kotlin
@JsonClass(generateAdapter = true)
class Item(val name: String)
@JsonClass(generateAdapter = true)
data class Cart(val items: List<Item>)
val adapter = Moshi.Builder().build().adapter(Cart::class.java)
val cart = Cart(items = listOf(Item("りんご"), Item("電球")))
val jsonString = adapter.toJson(cart)
println(jsonString) // {"items":[{"name":"りんご"},{"name":"電球"}]}
```
# Moshi-adapters
ようやく本題のMoshi-adaptersです。
これはいくつかのAdapterを追加するライブラリです。
現在(ver 1.8.0)では時刻に関するAdapterとEnumに関するAdapter、継承したクラスのAdapterがあります。
## EnumJsonAdapter
MoshiはもともとEnumとjsonの相互変換に対応しています。
```Kotlin
enum class Type {
A,B,UNKNOWN
}
val adapter = Moshi.Builder().build().adapter(Type::class.java)
val type = Type.A
val jsonString = adapter.toJson(type)
println(jsonString) // "A"
```
しかし、知らないStringが来たときはEnumにマップできず例外が投げられます。
```Kotlin
val fromJson = try {
adapter.fromJson("\"C\"")
} catch (e: Exception) {
null
}
println("fromJson:$fromJson") // fromJson:null
```
CというEnumは定義されていないので例外が発生して`fromJson`は`null`になってしまいます。
EnumJsonAdapterは知らないStringが来たときのデフォルト値を設定するためのAdapterです。
使い方を見ましょう。
```Kotlin
val adapter = Moshi.Builder()
.add(Type::class.java,
EnumJsonAdapter.create(Type::class.java).withUnknownFallback(Type.UNKNOWN))
.build().adapter(Type::class.java)
val fromJson = try {
adapter.fromJson("\"C\"")
} catch (e: Exception) {
null
}
println("fromJson:$fromJson") // fromJson:UNKNOWN
```
このように、未知の値がCがやってきたので`withUnknownFallback`で指定した`UNKNOWN`に変換されました。
## PolymorphicJsonAdapterFactory
あるスーパークラスがあって、それを継承したクラスのjson変換をしたい場合に利用します。
これを使うと、継承したクラスをjsonへシリアライズすることも、jsonからデシリアライズすることもできるようになります。
例を見ましょう。
```Kotlin
sealed class SealedItem(val name: String) {
@JsonClass(generateAdapter = true)
class Food(name:String) : SealedItem(name)
@JsonClass(generateAdapter = true)
class Appliances(name:String) : SealedItem(name)
}
@JsonClass(generateAdapter = true)
data class SealedCart(val items: List<SealedItem>)
```
このように、SealedItemというクラスがあって、それを継承したFoodとAppliancesがあったとします。
これをjsonに変換したり、jsonから戻したりするときに利用するのがPolymorphicJsonAdapterFactoryです。
使い方を見ましょう。
```Kotlin
val cart = SealedCart(items = listOf(SealedItem.Food("りんご"),
SealedItem.Appliances("電球")))
val adapter = Moshi.Builder()
.add(PolymorphicJsonAdapterFactory.of(SealedItem::class.java, "type")
.withSubtype(SealedItem.Food::class.java, "food")
.withSubtype(SealedItem.Appliances::class.java, "appliances"))
.build().adapter(SealedCart::class.java)
val jsonString = adapter.toJson(cart)
val fromJson = adapter.fromJson(jsonString)
println(jsonString)
// {"items":[{"type":"food","name":"SealedItem"},{"type":"appliances","name":"電球"}]}
```
このように、json変換したときに`of`で指定したプロパティが追加され、そのプロパティに`withSubtype`で型毎に指定した値がセットされるようになります。
これを使ってjson変換してくれるAdapterを生成できるのがPolymorphicJsonAdapterFactoryです。
# まとめ
Moshiを利用しているなら、ぜひMoshi-adaptersも利用しましょう!