使用Swift 4 JSONDecoder.DataDecodingStrategy.custom(_ :)自定义JSON数据解码

时间:2019-02-21 16:55:44

标签: json swift4

我正在寻找JSON自定义策略的数据,其解码方式如下:

JSONDecoder.DataDecodingStrategy.custom(_:)

某人是否有示例或链接? Apple documentation对此没有太多解释。

非常感谢您!

弗朗切斯科

1 个答案:

答案 0 :(得分:0)

这是自定义数据编码和解码策略的更全面示例。让我们从一个非常简单的数据模型开始:

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[$0], 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"}

解码

解码是在Swift中将JSON字符串转换为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($0, 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格式。