使用可编码解码JSON数组-Swift 5 [英] Decoding JSON array with codable - Swift 5

查看:61
本文介绍了使用可编码解码JSON数组-Swift 5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在以下链接中解码json数据

I would like to decode the json data in the following link

但是,rowSet数据是数组内部的一组json数组.如何设置可编码结构以解码此数据?我可以设置以下结构来解码其他数据.

However, the rowSet data is an set of json array in inside an array. How to set up the codable struct to decode this data? I am able to set up the following struct to decode the other data.

import Foundation

struct leagueLeader: Codable {
    
    var resource: String
    var parameters: parameters
    
}

struct parameters: Codable {
    var LeagueID: String
    var PerMode: String
    var StatCategory: String
    var Season: String
    var SeasonType: String
}

struct resultSet: Codable {
    
    var name: String
    var headers: [String]

}

推荐答案

困难的部分是处理应该包含多种数据类型的 rowSet

The hard part is dealing with rowSet that supposed to contains multiple data types

{
  "rowSet": [
    [
      1,
      1610612756,
      "PHX",
      "Phoenix Suns",
      1987
    ]
  ]
}

解决方案是声明一个枚举,每个枚举都有一个表示可编码数据类型的关联值

The solution is to declare an enum that each case has an associated value representing a codable data type

enum RowSet: Codable, Equatable {
    case integer(Int)
    case string(String)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(Int.self) {
            self = .integer(x)
            return
        }
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        throw DecodingError.typeMismatch(RowSet.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for RowSet"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .integer(let x):
            try container.encode(x)
        case .string(let x):
            try container.encode(x)
        }
    }
}

完整模型:

import Foundation

struct Leader: Codable, Equatable {
    let resource: String?
    let parameters: Parameters?
    let resultSets: [ResultSet]?
}

struct Parameters: Codable, Equatable {
    let leagueId, season, seasonType, perMode: String?
    let playerOrTeam: String?

    enum CodingKeys: String, CodingKey {
        case leagueId = "LeagueID"
        case season = "Season"
        case seasonType = "SeasonType"
        case perMode = "PerMode"
        case playerOrTeam = "PlayerOrTeam"
    }
}

struct ResultSet: Codable, Equatable {
    let name: String?
    let headers: [String]?
    let rowSet: [[RowSet]]?
}

enum RowSet: Codable, Equatable {
    case integer(Int)
    case string(String)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(Int.self) {
            self = .integer(x)
            return
        }
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        throw DecodingError.typeMismatch(RowSet.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for RowSet"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .integer(let x):
            try container.encode(x)
        case .string(let x):
            try container.encode(x)
        }
    }
}

这篇关于使用可编码解码JSON数组-Swift 5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆