swift - 使用 JSONDecoder 解码数字 Snake_case 键

标签 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 转换为驼峰命名法。 :

This strategy follows these steps to convert JSON keys to camel-case:

  1. Capitalize each word that follows an underscore.

  2. Remove all underscores that aren't at the very start or end of the string.

  3. Combine the words into a single string.

因此,在这种情况下:

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

但是,当尝试解码此响应时,会引发 image1000x1000 键的 keyNotFound 错误 ( 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 找不到相应的 key ?

最佳答案

您可以通过反向运行该过程来了解算法的期望;使用 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 作为 key ,那么您就完成了。如果没有,你将不得不做这样的事情:

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

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

另一个选择是实现自定义 key 编码策略。最终可能会减少代码。请参阅KeyEncodingStrategy了解更多相关信息。

关于swift - 使用 JSONDecoder 解码数字 Snake_case 键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56782697/

相关文章:

swift - 无法使用类型为 'decode' 的参数列表调用 '(Decodable, from: Data)'

ios - 从 API 调用返回的 base64encoded 字符串在数据之后显示为 nil(base64encoded : data) is ran

ios - 从本地文件获取对象中数据的问题

arrays - 如何从具有重复范围的数组中获取具有唯一范围的数组?

Swift PDF 渲染任何 UIView 或 UIViewController PDFKit

ios - 调用云代码 Parse Swift

json - swift 4 : JSONDecoder fails in one specific case - "The operation could not be completed"

ios - 通过访问图像的标签以编程方式删除图像

swift - 如何使用 SwiftUI 将 View 拉伸(stretch)到其父框架?