简体   繁体   中英

Try to parse JSON Array of Arrays on Swift

Here is the json code:

{
  
    "rows":
        [[{
            "text":"some text",
            "type":{
                "type":"inlineUrl",
                "url":"https://nothing.com"
            }
        }],
        [{
            "text":"some text",
            "type":{
                "type":"inlineCallback",
                "data":"some data"
            }
        },
        {
            "text":"some text",
            "type":{
                "type":"inlineCallback",
                "data":"some data"
            }
        }
        ]]
        
}

A more abbreviated would look like: Rows = [ [Row1], [Row2, Row3] ]

And I'm trying to get it to work like this:

struct ReplyHandler: Codable {
    let rows: [RowsHandler]

    enum CodingKeys: String, CodingKey {
        case rows
    }
}

struct RowsHandler: Codable {
    let row1: [RowHandler]
    let row2: [Row2Handler]
    
    enum CodingKeys: String, CodingKey {
        case row1
        case row2
    }
}

struct RowHandler: Codable {
    let text: String
    let type: TypeHandler
    
    enum CodingKeys: String, CodingKey {
        case type = "type"
        case text = "text"
    }
}

struct Row2Handler: Codable {
    let row1: RowHandler
    let row2: RowHandler

    enum CodingKeys: String, CodingKey {
        case row1
        case row2
    }
}

struct TypeHandler: Codable {
    let type: String
    let url: String

    enum CodingKeys: String, CodingKey {
        case type = "type"
        case url = "url"
    }
    
}

But Xcode compiler gives this error:

Expected to decode String but found an array instead.

Don't understand how to properly nest other arrays in the array

While posting my question, I noticed that the arrays in "type" are different: the first row have url, the second and third have data, but anyway, it's not a point.

You can simplify your model to something like this:

struct ReplyHandler: Codable {
    let rows: [[RowHandler]]
}

struct RowHandler: Codable {
    let text: String
    let type: TypeHandler
}

struct TypeHandler: Codable {
    let type: String
    var url: String?
    var data: String?
}

Notice that url and data properties in TypeHandler are optionals to cover both cases.

Although manual JSON parsing is useful I think that it must be much easier to use tool like this https://app.quicktype.io/ to convert JSON into Swift classes or structs

For you JSON it provides this result

// MARK: - Welcome
struct Welcome: Codable {
    let rows: [[Row]]
}

// MARK: - Row
struct Row: Codable {
    let text: String
    let type: TypeClass
}

// MARK: - TypeClass
struct TypeClass: Codable {
    let type: String
    let url: String?
    let data: String?
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM