`convertFromSnakeCase`策略不适用于Swift

时间:2018-04-17 15:06:25

标签: ios swift codable jsondecoder

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

以下是example

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。我错过了什么吗?

1 个答案:

答案 0 :(得分:9)

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

在您的情况下,JSON中的student_id键将studentId映射到.convertFromSnakeCase。转换的确切算法是given in the documentation

  
      
  1. 将每个单词大写下划线。

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

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

  6.         

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

         

    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
  }
}