简体   繁体   中英

How to make structs for this JSON with Decodable protocol?

I've got this JSON:

{
    "$type": "DTOMapper.DTOResponseList`1[[Telemed.Dto.DTOTip, Telemed.Dto]], DTOMapper",
    "ResponseList": {
        "$type": "System.Collections.Generic.List`1[[Telemed.Dto.DTOTip, Telemed.Dto]], mscorlib",
        "$values": [
            {
                "$type": "Telemed.Dto.DTOTip, Telemed.Dto",
                "Title": "NO TE JUNTES CON LUQUITAS",
                "Text": "Porque si tenes un amigo lucas y otro amigo lucas, tenés dos lucas. Pero no te sirven para pagar nada",
                "GroupName": "TGC.Tips1",
                "ConfigurationPath": "TelemedGlobalConfig>Tips>Tips[0]"
            },
            {
                "$type": "Telemed.Dto.DTOTip, Telemed.Dto",
                "Title": "no te emborraches en las fiestas",
                "Text": "Terminarás pateando globos",
                "GroupName": "TGC.Tips2",
                "ConfigurationPath": "TelemedGlobalConfig>Tips>Tips[1]"
            }
        ]
    },
    "StatusCode": 200,
    "ErrorId": 0
}

And I'm trying to get access to Title and Text from the array $values .

Here are my current structs but Root gives me errors.

struct Root : Decodable {  // <<< Type 'Root' does not conform to protocol 'Decodable'
    private enum CodingKeys : String, CodingKey { case responseList = "ResponseList" }
    let responseList : ResponseList // <<< Use of undeclared type 'ResponseList'
}

struct Values : Decodable {
    private enum CodingKeys : String, CodingKey {
        case title = "Title"
        case text = "Text"
    }

    let title : String
    let text : String
}

What is the correct way to make this? Also, do I have to make a struct and let for everything? Even for things I won't use, like $type , GroupName ?

What is the correct way to make this?

do { 
    let res = try JSONDecoder().decode(Root.self, from: data) 
}
catch { 
    print(error)
}

struct Root: Codable {
    let type: String
    let responseList: ResponseList
    let statusCode, errorID: Int

    enum CodingKeys: String, CodingKey {
        case type = "$type"
        case responseList = "ResponseList"
        case statusCode = "StatusCode"
        case errorID = "ErrorId"
    }
}

// MARK: - ResponseList
struct ResponseList: Codable {
    let type: String
    let values: [Value]

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

// MARK: - Value
struct Value: Codable {
    let title, text:String // left only <<<  access to Title and Text
    enum CodingKeys: String, CodingKey {
        case title = "Title"
        case text = "Text"

    }
}

Do I have to make a struct and let for everything? Even for things I won't use, like $type, GroupName?

No only properties that you'll use

You could try this:

struct YourStructName: Codable {
    var statusCode: Int
    var errorId: Int
    var type: String // Maybe make this an enum case
    var response: Response

    enum CodingKeys: String, CodingKey {
        case statusCode = "StatusCode"
        case errorId = "ErrorId"
        case type = "$type"
        case response = "ResponseList"
    }

    struct Response: Codable {
        var type: String // Again, consider making this an enum case
        var values: [ResponseValue]

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

        struct ResponseValue: Codable { 
            var title: String
            var text: String 

            enum CodingKeys: String, CodingKey { 
                case title = "Title"
                case text = "Text" 
            }
        }
    }
}

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