With all the posts out there about Moshi and people's confusion (including my own) about how to parse a list, I can't believe that this is this difficult. I have an object that has two nested lists. I can't get either of them to parse.
{
    "respondent_id": "1",
    "completion_status": "completed",
    "date_modified": "2023-12-05T17:41:49Z",
    "date_start": "2023-12-05T17:41:41Z",
    "responses": [
        {
            "page_index": 0,
            "page_id": "4771",
            "question_id": "1645",
            "question_index": 0,
            "question_value": "Do you like me?",
            "answers": [
                {
                    "row_index": 0,
                    "row_id": "1",
                    "row_value": "",
                    "column_index": 10,
                    "column_id": "1",
                    "column_value": "Absolutely!"
                }
            ]
        },
        {
            "page_index": 0,
            "page_id": "4771",
            "question_id": "1614",
            "question_index": 1,
            "question_value": "What's the primary reason for your rating?",
            "answers": [
                {
                    "text_response": "Because you are cool"
                }
            ]
        },
        {
            "page_index": 0,
            "page_id": "4771",
            "question_id": "1614",
            "question_index": 2,
            "question_value": "How much do you like me?",
            "answers": [
                {
                    "row_index": 0,
                    "row_id": "1182",
                    "row_value": "More than anyone else"
                }
            ]
        }
    ]
}
So I created these data classes to parse this:
@JsonClass(generateAdapter = true)
data class SurveyResponse(
    @SerializedName("respondent_id") val respondentId: String,
    @SerializedName("completion_status") val completionStatus: String,
    @SerializedName("date_modified") val dateModified: String,
    @SerializedName("date_start") val dateStart: String,
    @Json(name = "responses") val responses: List<SurveyQuestion>
)
@JsonClass(generateAdapter = true)
data class SurveyQuestion(
    @SerializedName("page_index") val pageIndex: Int,
    @SerializedName("page_id") val pageId: String,
    @SerializedName("question_id") val questionId: String,
    @SerializedName("question_index") val questionIndex: Int,
    @SerializedName("question_value") val questionValue: String,
    @Json(name = "answers") val answers: List<Answer>
)
@JsonClass(generateAdapter = true)
data class Answer(
    @SerializedName("row_index") val rowIndex: Int,
    @SerializedName("row_id") val rowId: String,
    @SerializedName("row_value") val rowValue: String = "",
    @SerializedName("column_index") val columnIndex: Int,
    @SerializedName("column_id") val columnId: String,
    @SerializedName("column_value") val columnValue: String
)
I even tried to create a coupld of custom adapters, although I have no reason to believe that they are necessary:
class ResponsesAdapter {
    @FromJson
    fun arrayListFromJson(list: List<SurveyQuestion>): ArrayList<SurveyQuestion> = ArrayList(list)
}
class AnswersAdapter {
    @FromJson
    fun arrayListFromJson(list: List<Answer>): ArrayList<Answer> = ArrayList(list)
}
And then wrote this code to parse this:
val moshi: Moshi = Moshi
    .Builder()
    .add(ResponsesAdapter())
    .add(AnswersAdapter())
    .build()
val jsonAdapter: JsonAdapter<SurveyResponse> = moshi.adapter<SurveyResponse>()
val surveyResponse = jsonAdapter.fromJson(jsonString)
I've tried many other ways to create a custom adapter, but I always get this error, which I have seen in many other posts:
java.lang.IllegalArgumentException: No JsonAdapter for java.util.ArrayList<java.lang.String>, you should probably use List instead of ArrayList (Moshi only supports the collection interfaces by default) or else register a custom JsonAdapter.
This message is particularly confusing because there is no ArrayList involved and there is no string (other than the raw string that i am trying to parse).
I've reached the point where I am just throwing stuff against the wall to see what sticks. This cannot be that difficult to resolve, but I don't see the solution.
EDIT
Following up on Faruk's answer below. I had tried to use KotlinJsonAdapterFactory but had written that line incorrectly. I wrote .adapter<SurveyResponse::class.java>(). Once I fixed that, the app no longer crashes.
The other part of his answer that fixed this was to change the annotations in the data classes from:
@SerializedName("whatever")
to:
@Json(name = "whatever")
Without that, all the values parsed as null.
 
                        
First of all, you should handle that the values can be null.
You don't need adapters. Just use
KotlinJsonAdapterFactory()