使用JSONDecoder解码数字snake_case密钥

时间:2019-06-27 01:13:31

标签: swift jsondecoder

我有以下JSON对象,该对象将使用JSONDecoder转换为对象:

{
  "first_key": 3,
  "image_1000x1000": "location"
}

这映射到以下Swift模型:

struct Response: Decodable {
  var firstKey: Int
  var image1000x1000: String
}

通过将JSONDecoder.convertFromSnakeCase选项一起使用,JSON中的snake_case键通过使用the algorithm defined in the documentation转换为camelCase:

  

此策略遵循以下步骤将JSON密钥转换为驼峰式:

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

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

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

  6.   

因此,在这种情况下:

  • first_key变成firstKey(如预期)
  • image_1000x1000应该成为image1000x1000

但是,当尝试解码此响应时,会抛出keyNotFound键的image1000x1000错误(see this live example):

let json = "{\"first_key\": 3, \"image_1000x1000\": \"location\"}".data(using: .utf8)!
do {
  let decoder = JSONDecoder()
  decoder.keyDecodingStrategy = .convertFromSnakeCase
  let response = try decoder.decode(Response.self, from: json)
  print(response)
} catch let e {
  print(e)
}

我的image_1000x1000驼峰式大小写转换有什么不正确之处,为什么JSONDecoder找不到对应的密钥?

1 个答案:

答案 0 :(得分:0)

您可以通过反向运行该进程来查看算法的期望值;使用JSONEncoder编码数据并检查输出:

struct Response: Codable {
    var firstKey: Int
    var image1000x1000: String
}

let test = Response(firstKey: 10, image1000x1000: "secondKey" )

let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
let data = try encoder.encode(test)
print(String(data: data, encoding: .utf8)!)

这将产生:

{"first_key":10,"image1000x1000":"secondKey"}

因此,如果您可以控制JSON并且可以将image1000x1000作为密钥使用,那么您就完成了。如果不是,则必须执行以下操作:

struct Response: Codable {
    var firstKey: Int
    var image1000x1000: String

    private enum CodingKeys: String, CodingKey {
        case image1000x1000 = "image_1000x1000"
        case firstKey = "first_key"
    }
}

另一个选择是实现自定义键编码策略。最终可能会减少代码量。有关更多信息,请参见KeyEncodingStrategy