to make your PO happy What we have: ▸ API that can not be (easily) changed ▸ JSON can be different (to your expectations) What we want: ▸ Less content related crashes ▸ get rid of tedious, nested null checks ▸ filter „broken“ content
class Article { public String id; public String title; public Image cell_image; public User author; public Video video; public String subtitle; public List<Content> content; public int like_count; public List<Comment> comments; public Date published_at; // Constructors, Getters, Setters, ... }
class Article( val id: String, val title: String, val cell_image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val like_count: Int = 0, val comments: List<Comment> = listOf(), val published_at: Date = Date(0) )
class Article( val id: String, val title: String, val cell_image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val like_count: Int = 0, val comments: List<Comment> = listOf(), val published_at: Date = Date(0) )
class Article( val id: String, val title: String, val image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val likeCount: Int = 0, val comments: List<Comment> = listOf(), val publishedAt: Date = Date(0) )
class Article( val id: String, val title: String, @Json(name = "cell_image") val image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), @Json(name = "like_count") val likeCount: Int = 0, val comments: List<Comment> = listOf(), @Json(name = "published_at") val publishedAt: Date = Date(0) )
class Article( val id: String, val title: String, val image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val likeCount: Int = 0, val comments: List<Comment> = listOf(), val publishedAt: Date = Date(0) )
class Article( val id: String, val title: String, val image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val likeCount: Int = 0, val comments: List<Comment> = listOf(), val publishedAt: Date = Date(0) )
class Article( val id: String, val title: String, val image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val likeCount: Int = 0, val comments: List<Comment> = listOf(), val publishedAt: Date = Date(0) )
class Article( val id: String, val title: String, val image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val likeCount: Int = 0, val comments: List<Comment> = listOf(), val publishedAt: Date = Date(0) )
class Article( val id: String, val title: String, val image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val likeCount: Int = 0, val comments: List<Comment> = listOf(), val publishedAt: Date = Date(0) )
class Article( val id: String, val title: String, val image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val likeCount: Int = 0, val comments: List<Comment> = listOf(), val publishedAt: Date = Date(0) )
class Article( val id: String, val title: String, val image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val likeCount: Int = 0, val comments: List<Comment> = listOf(), val publishedAt: Date = Date(0) )
to setup Moshi implementation „com.squareup.moshi:moshi:1.6.0“ // Version A) implementation „com.squareup.moshi:moshi-kotlin:1.6.0“ // adds kotlin.reflect library !
to setup Moshi implementation „com.squareup.moshi:moshi:1.6.0“ // Version A) implementation „com.squareup.moshi:moshi-kotlin:1.6.0“ // Version B) Kapt „com.squareup.moshi:moshi-kotlin-codegen:1.6.0“
to setup Moshi - with reflection val moshi = Moshi.Builder() // "... here be adapters# .add(KotlinJsonAdapterFactory()) //constructor default values$ .build() https://github.com/square/moshi/issues/315
to setup Moshi - with code generation data class Article( val title: String, val image: Image, // … ) val moshi = Moshi.Builder() // no Kotlin Adapter needed .build()
to setup Moshi - with code generation @JsonClass(generateAdapter = true) data class Article( val title: String, val image: Image, // … ) val moshi = Moshi.Builder() // no Kotlin Adapter needed .build()
to setup Moshi - with code generation @JsonClass(generateAdapter = true) data class Article( val title: String, val image: Image, // … ) val moshi = Moshi.Builder() // no Kotlin Adapter needed .build() Step 3) use Moshi with Retrofit https://proandroiddev.com/a69c2621708b
= true) data class Article( val id: String, val title: String, val image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val likeCount: Int = 0, val comments: List<Comment> = listOf(), val publishedAt: Date = Date(0) )
test ▸ What is Date ! -> Successful ✅ ▸ Not all mandatory fields are present? ! -> Successful ✅ ▸ filter general parsing errors ▸ more robust parsing ▸ There can be nulls in non-nullable lists? ! -> Crash &
test ▸ What is Date ! -> Successful ✅ ▸ Not all mandatory fields are present? ! -> Successful ✅ ▸ filter general parsing errors ▸ more robust parsing ▸ There can be nulls in non-nullable lists?* ! -> Crash & *https://github.com/square/moshi/issues/331
= true) data class Article( val id: String, val title: String, val cell_image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content> = listOf(), val like_count: Int = 0, val comments: List<Comment> = listOf(), val published_at: Date = Date(0) )
= true) data class Article( val id: String, val title: String, val cell_image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content?> = listOf(), val like_count: Int = 0, val comments: List<Comment?> = listOf(), val published_at: Date = Date(0) )
= true) data class Article( val id: String, val title: String, val cell_image: Image, val author: User, val video: Video? = null, val subtitle: String = EMPTY_STRING, val content: List<Content!> = listOf(), val like_count: Int = 0, val comments: List<Comment!> = listOf(), val published_at: Date = Date(0) )
▸ Kotlin is fun ▸ Immutable, non-nullable and constructor default values ▸ Parse JSON into Data Classes with Moshi ▸ Filter „broken“ content from bottom up ▸ Workaround for List-Bug in Moshi ▸ maybe not suited for very big set of models