动态(但称为另一个键值)JSON 解码与 Swift Decodable



我已经看了类似问题的答案,我无法很好地理解编码密钥,此外它并不完全适用于我的情况,因为密钥不是完全"未知"它是前一个密钥的值。 我的 API:

{
"api": {
"results": 1,
"fixtures": [
{
"homeTeam": {
"team_name": "Tottenham"
},
"awayTeam": {
"team_name": "Everton"
},
"lineups": {
"Tottenham": {
"formation": "4-2-3-1"
},
"Everton": {
"formation": "4-2-3-1"
}
}
}
]
}
}

我的代码:

class matchApiObject: Decodable
{
let fixtures: [fixture]
init (fixtures: [fixture])
{
self.fixtures = fixtures
}
}
class fixture: Decodable
{
let homeTeam: matchHomeTeamObject?
let lineups: lineUpsObject?
init (homeTeam: matchHomeTeamObject?, lineups: lineUpsObject?)
{
self.homeTeam = homeTeam
self.lineups = lineups
}
}
class matchHomeTeamObject: Decodable
{
let team_name: String?
init (team_name: String?)
{
self.team_name = team_name
}
}
class lineUpsObject: Decodable
{
struct homeLineUp: Decodable
{
let formation: String?
init(formation: String?)
{
self.formation = formation
}
}
struct awayLineUp: Decodable
{
let formation: String?
init (formation: String?)
{
self.formation = formation
}
}
}

显然,阵容对象的键不会是"homeLineUp",而是按照 api 示例,homeTeam.team_name的值。

所以我想象的解决方案是:

class lineUpsObject: Decodable
{
struct homeTeam.team_name: Decodable
{
let formation: String?
init(formation: String?)
{
self.formation = formation
}
}
struct awayTeam.team_name: Decodable
{
let formation: String?
init (formation: String?)
{
self.formation = formation
}
}
}

这是不可能的,我知道我必须为此使用编码键,但我不明白如何将键的名称声明为上一个键值的值我不明白 stringValue: 字符串或 intValue: intValue: int 在编码键答案中做什么或它们如何在这里应用, 谢谢。

一个简单的解决方案是将lineups解码为字典,我用起始大写字母命名所有结构以符合命名约定。

不需要init方法

struct Root : Decodable {
let api : API
}
struct API : Decodable {
let results : Int
let fixtures : [Fixture]
}
struct Fixture : Decodable {
let homeTeam, awayTeam: Team
let lineups : [String:Lineup]
}
struct Team  : Decodable {
let teamName : String
}
struct Lineup : Decodable {
let formation : String
}

若要将snake_cased键转换为驼峰结构成员,请添加相应的策略

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

更复杂的解决方案是将formation数据放入Team结构中,但这需要在Fixture中实现init(from decoder:)方法。

最新更新