swift - 如何处理要在 swift 中作为 json 发送的空数组?

标签 swift swift5 codable decodable encodable

我正在尝试对数据进行编码,但很难处理没有类型的空数组,因为如果没有条目,我正在使用的 API 需要我发送 []

[
    {
        "RequestId": "5B6E36D9-8759-41BB-A0C0-EDFB116DFBB7",
        "DataSources": ["5B6E36D9-8759-41BB-A0C0-EDFB116DFBB7"],
        "GroupBy": [],
        "Filters": []
    }
]

上面是我必须发送的对象json。

struct ResponseElement: Encodable {
    let requestID: String
    let dataSources: [String]
    let groupBy: []
    let filters: []

    enum CodingKeys: String, CodingKey {
        case requestID = "RequestId"
        case dataSources = "DataSources"
        case groupBy = "GroupBy"
        case filters = "Filters"
    }
}

let data = ResponseElement(requestID: "5B6E36D9-8759-41BB-A0C0-EDFB116DFBB7",
                           dataSources: ["5B6E36D9-8759-41BB-A0C0-EDFB116DFBB7", ["5B6E36D9-8759-41BB-A0C0-EDFB116DFBB7]"],
                           groupBy: [],
                           filters: [])

let jsonEncoder = JSONEncoder()
let data = try! jsonEncoder.encode(data)

请注意,在创建数据变量时,我必须将 groupBy、过滤器 作为空数组 [] 传递,我尝试使用 [nil],它在之后作为 [null]编码,但它在我的情况下不起作用,它必须是 []

请问我该如何解决?

最佳答案

如果您知道数组将始终为空,则其类型为[Never]Never 是无法实例化的类型,因此该数组必然为空。

不幸的是,Never 不符合 Encodable。它应该。它应该自动符合每个协议(protocol)(这将使 Never 成为“底层类型”,这是类型系统中的一个很好的特性)。也就是说,提供一致性很简单:

extension Never: Encodable {
    public func encode(to encoder: Encoder) throws {
        // This line of code can never, ever run. It's impossible to
        // create a Never, so it's impossible to run its instance methods.
        fatalError()
    }
}

struct ResponseElement: Encodable {
    let requestID: String
    let dataSources: [String]
    let groupBy: [Never]
    let filters: [Never]

    ...
}

扩展标准库类型以符合标准库协议(protocol),您可能会感到不自在。这有点脆弱,因为 stdlib 将来可能会创建一致性,或者其他一些包可能会这样做,并且会发生冲突。因此,您可以通过创建自己的类型来明确地执行此操作,该类型对空的未加密容器进行编码:

struct EmptyArray: Encodable {
    func encode(to encoder: Encoder) throws {
        encoder.unkeyedContainer()
    }
}

struct ResponseElement: Encodable {
    let requestID: String
    let dataSources: [String]
    let groupBy: EmptyArray
    let filters: EmptyArray
    ...
}

最后,您可以手动执行编码并删除不必要的属性(这就是我自己的做法):

struct ResponseElement: Encodable {
    let requestID: String
    let dataSources: [String]

    enum CodingKeys: String, CodingKey {
        case requestID = "RequestId"
        case dataSources = "DataSources"
        case groupBy = "GroupBy"
        case filters = "Filters"
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(requestID, forKey: .requestID)
        try container.encode(dataSources, forKey: .dataSources)
        container.nestedUnkeyedContainer(forKey: .groupBy)
        container.nestedUnkeyedContainer(forKey: .filters )
    }
}

关于swift - 如何处理要在 swift 中作为 json 发送的空数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73278954/

相关文章:

ios - 如何在 Swift 4 中验证 JSON?

swift - 如何将符合 Codable 协议(protocol)的对象数组转换为 Dictionary 数组?

ios - 根据 SwiftUI 中的切换值更改文本

ios - CanOpenUrl 方法不适用于 ios 9

php - Swift 从网站读取 HTML 标签

c++ - 在 XCode 中桥接 C++ 和 Swift,正确的build设置是什么?

swift - 如何在 Swift 中的英镑符号字符串中应用空格?

ios - 选项卡栏角半径不显示透明角

json - 当键根据用户输入更改时如何从 json 解码变量?

swift - UIImageView 在 StackView 和 TableViewCell 中不是自动高度