一尘不染

`convertFromSnakeCase`策略不适用于Swift中的自定义`CodingKeys`

swift

我尝试使用Swift 4.1的新功能在JSON解码期间将蛇案转换为camelCase。

这是示例

struct StudentInfo: Decodable {
    internal let studentID: String
    internal let name: String
    internal let testScore: String

    private enum CodingKeys: String, CodingKey {
        case studentID = "student_id"
        case name
        case testScore
    }
}

let jsonString = """
{"student_id":"123","name":"Apple Bay Street","test_score":"94608"}
"""

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let decoded = try decoder.decode(StudentInfo.self, from: Data(jsonString.utf8))
    print(decoded)
} catch {
    print(error)
}

我需要提供习惯,CodingKeys因为该convertFromSnakeCase策略无法推断首字母缩略词或首字母缩写(例如studentID)的大小写,但我希望该convertFromSnakeCase策略仍然适用testScore。但是,解码器会引发错误(“与键CodingKeys无关的值”),看来我不能同时使用convertFromSnakeCase策略和自定义CodingKeys。我想念什么吗?


阅读 298

收藏
2020-07-07

共1个答案

一尘不染

JSONDecoder(和JSONEncoder)的密钥策略适用于有效负载中的所有密钥,包括您为其提供自定义编码密钥的密钥策略。解码时,JSON密钥将首先使用给定的密钥策略进行映射,然后解码器将CodingKeys针对要解码的给定类型咨询。

在你的情况下,student_id在你的JSON密钥将被映射到studentId.convertFromSnakeCase文档中给出了转换的确切算法:

  1. 下划线后的每个单词均大写。

  2. 删除所有不在字符串开头或结尾的下划线。

  3. 将单词组合成一个字符串。

以下示例显示了应用此策略的结果:

fee_fi_fo_fum

转换为: feeFiFoFum

feeFiFoFum

转换为: feeFiFoFum

base_uri

转换为: baseUri

因此,您需要更新您的内容CodingKeys以使其与此匹配:

internal struct StudentInfo: Decodable, Equatable {
  internal let studentID: String
  internal let name: String
  internal let testScore: String

  private enum CodingKeys: String, CodingKey {
    case studentID = "studentId"
    case name
    case testScore
  }
}
2020-07-07