We shall parse {"geo":"1.0, 2.0"}
into a LocationType
class to store the latitude
and longitude
.
LocationType
.
class LocationType( @Transient var lat: Double? = null, @Transient var lng: Double? = null) { // accept android.location.Location constructor(location: Location?): this(location?.latitude, location?.longitude) companion object { fun fromJson(data: String): LocationType? { if (data.isEmpty()) { return null } val item = LocationType() item.fromJson(data) return item } } fun setValue(lat: Double, lng: Double) { this.lat = lat this.lng = lng } fun isNull(): Boolean { return lat == null || lng == null } private fun fromJson(data: String) { val tokens = data.split(",\\s?".toRegex()) if (tokens.size == 2) { lat = tokens[0].toDouble() lng = tokens[1].toDouble() } else { lat = null lng = null } } fun toJson(): String? { if (isNull()) { return null } return "$lat, $lng" }}
LocationAdapter
.
class LocationAdapter { @ToJson @Nullable fun toJson(@Nullable value: LocationType?): String? { return value?.toJson() } @FromJson fun fromJson(@Nullable data: String?): LocationType? { if (data == null) { return null } return LocationType.fromJson(data) }}
Setup Moshi
val moshi = Moshi.Builder() .add(LocationAdapter()) .add(KotlinJsonAdapterFactory()) .build()
Test Code.
data class PhotoPin ( @Json(name = "geo") var location: LocationType? = null )
@RunWith(AndroidJUnit4::class)class MoshiTest { lateinit var moshi: Moshi lateinit var adapter: JsonAdapter<PhotoPin> @Before fun init() { moshi = Moshi.Builder() .add(LocationAdapter()) .add(KotlinJsonAdapterFactory()) .build() adapter = moshi.adapter<PhotoPin>(PhotoPin::class.java) } @Test fun testLocationEmpty() { var item = adapter.fromJson("""{"geo": ""}""")!! assertThat(item.location, Is(nullValue())) } @Test fun testLocationNull() { var item = adapter.fromJson("""{"geo": null}""")!! assertThat(item.location, Is(nullValue())) } @Test fun testLocationValue() { var item = adapter.fromJson("""{"geo":"1.0, 2"}""")!! assertThat(item.location, Is(notNullValue())) assertThat(item.location?.lat, Is(1.0)) assertThat(item.location?.lng, Is(2.0)) } @Test fun testLocationValueToJson() { var item = PhotoPin() item.location = LocationType(1.0, 2.0) val data = adapter.toJson(item) assertThat(data.contains(""""geo":"1.0, 2.0""""), Is(true)) item = adapter.fromJson(data)!! assertThat(item.location?.lat, Is(1.0)) assertThat(item.location?.lng, Is(2.0)) } @Test fun testLocationEmptyToJson() { var item = PhotoPin() val data = adapter.serializeNulls().toJson(item) assertThat(item.location, Is(nullValue())) assertThat(data.contains(""""geo":null"""), Is(true)) item = adapter.fromJson(data)!! assertThat(item.location, Is(nullValue())) } }