自定义 JSON 数据解码使用 Swift 4 JSONDecoder.DataDecodingStrategy.custom(_:)
Custom JSON data decode using Swift 4 JSONDecoder.DataDecodingStrategy.custom(_:)
我正在寻找 JSON 自定义策略的示例数据解码:
JSONDecoder.DataDecodingStrategy.custom(_:)
有人有例子或 link(s) 吗? Apple documentation就不多解释了。
非常感谢!
弗朗切斯科
这里有一个更全面的自定义数据编码和解码策略的例子。让我们从一个非常简单的数据模型开始:
struct Model: Codable {
var data: Data
}
编码
Swift中的Data
被编码成JSON中的字符串。默认编码使用 Base64,因此如果您将 data
分配给组成字符串 "Hello world" 的字节,您将获得以下数据:
let m = Model(data: "Hello world".data(using: .utf8)!)
let json = try JSONEncoder().encode(m)
let jsonString = String(data: json, encoding: .utf8)!
print(jsonString) // {"data":"SGVsbG8gd29ybGQ="}
但假设您想使用十六进制代码而不是 Base64。您可以编写自定义数据编码函数:
func customDataEncoder(data: Data, encoder: Encoder) throws {
let str = (0..<data.count).map {
String(data[[=12=]], radix: 16, uppercase: true)
}.joined(separator: " ")
var container = encoder.singleValueContainer()
try container.encode(str)
}
let encoder = JSONEncoder()
encoder.dataEncodingStrategy = .custom(customDataEncoder)
let m = Model(data: "Hello world".data(using: .utf8)!)
let json = try JSONEncoder().encode(m)
let jsonString = String(data: json, encoding: .utf8)!
print(jsonString) // {"data":"48 65 6C 6C 6F 20 77 6F 72 6C 64"}
解码
解码是将JSON字符串在Swift中变成Data
的过程。如果字符串是 Base64 编码的,则您无需执行任何其他操作。但是由于我们以十六进制编码 Data
,您需要提供自定义数据解码器:
func customDataDecoder(decoder: Decoder) throws -> Data {
let container = try decoder.singleValueContainer()
let str = try container.decode(String.self)
let bytes = str.components(separatedBy: " ").map {
UInt8([=13=], radix: 16)!
}
return Data(bytes)
}
let decoder = JSONDecoder()
decoder.dataDecodingStrategy = .custom(customDataDecoder)
let decodedM = try decoder.decode(Model.self, from: json)
print(m.data == decodedM.data) // true
注:当我说“Swift中的Data
被编码成JSON中的字符串”时,大部分都是对的时代,但不必每次都如此。没有什么能阻止你将 属性 data
编码成这样的东西:
{
"data": {
"count": 11,
"string": "Hello world",
"hex": "48 65 6C 6C 6F 20 77 6F 72 6C 64"
}
}
当然,您必须更新自定义解码器以匹配 JSON 格式。
我正在寻找 JSON 自定义策略的示例数据解码:
JSONDecoder.DataDecodingStrategy.custom(_:)
有人有例子或 link(s) 吗? Apple documentation就不多解释了。
非常感谢!
弗朗切斯科
这里有一个更全面的自定义数据编码和解码策略的例子。让我们从一个非常简单的数据模型开始:
struct Model: Codable {
var data: Data
}
编码
Swift中的Data
被编码成JSON中的字符串。默认编码使用 Base64,因此如果您将 data
分配给组成字符串 "Hello world" 的字节,您将获得以下数据:
let m = Model(data: "Hello world".data(using: .utf8)!)
let json = try JSONEncoder().encode(m)
let jsonString = String(data: json, encoding: .utf8)!
print(jsonString) // {"data":"SGVsbG8gd29ybGQ="}
但假设您想使用十六进制代码而不是 Base64。您可以编写自定义数据编码函数:
func customDataEncoder(data: Data, encoder: Encoder) throws {
let str = (0..<data.count).map {
String(data[[=12=]], radix: 16, uppercase: true)
}.joined(separator: " ")
var container = encoder.singleValueContainer()
try container.encode(str)
}
let encoder = JSONEncoder()
encoder.dataEncodingStrategy = .custom(customDataEncoder)
let m = Model(data: "Hello world".data(using: .utf8)!)
let json = try JSONEncoder().encode(m)
let jsonString = String(data: json, encoding: .utf8)!
print(jsonString) // {"data":"48 65 6C 6C 6F 20 77 6F 72 6C 64"}
解码
解码是将JSON字符串在Swift中变成Data
的过程。如果字符串是 Base64 编码的,则您无需执行任何其他操作。但是由于我们以十六进制编码 Data
,您需要提供自定义数据解码器:
func customDataDecoder(decoder: Decoder) throws -> Data {
let container = try decoder.singleValueContainer()
let str = try container.decode(String.self)
let bytes = str.components(separatedBy: " ").map {
UInt8([=13=], radix: 16)!
}
return Data(bytes)
}
let decoder = JSONDecoder()
decoder.dataDecodingStrategy = .custom(customDataDecoder)
let decodedM = try decoder.decode(Model.self, from: json)
print(m.data == decodedM.data) // true
注:当我说“Swift中的Data
被编码成JSON中的字符串”时,大部分都是对的时代,但不必每次都如此。没有什么能阻止你将 属性 data
编码成这样的东西:
{
"data": {
"count": 11,
"string": "Hello world",
"hex": "48 65 6C 6C 6F 20 77 6F 72 6C 64"
}
}
当然,您必须更新自定义解码器以匹配 JSON 格式。