【问题标题】:dynamic dictionary name decoder json动态字典名称解码器json
【发布时间】:2018-03-15 20:44:40
【问题描述】:

Swift 4. 我的情况与Using Codable on a dynamic type/object 非常相似,但对我来说,变化的变量是字典的名称,而不是里面的键。它看起来像:

{
    "customName": {
        "constantKey": Double,
        "constantKey2": Double,
    }
}

这是我要更改的代码,它已被提议作为另一个问题的答案,我做了很少的更改:

 struct GenericCodingKeys: CodingKey {
    var intValue: Int?
    var stringValue: String

    init?(intValue: Int) { self.intValue = intValue; self.stringValue = "\(intValue)" }
    init?(stringValue: String) { self.stringValue = stringValue }

    static func makeKey(name: String) -> GenericCodingKeys {
        return GenericCodingKeys(stringValue: name)!
    }
}


struct MyModel: Decodable {
    var customName: [String: Double]

    private enum CodingKeys: String, CodingKey {
        case customName
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)

    customName = [String: String]()
    let subContainer = try container.nestedContainer(keyedBy: GenericCodingKeys.self, forKey: .customName)
    for key in subContainer.allKeys {
        customName[key.stringValue] = try subContainer.decode(Double.self, forKey: key)
        }
    }
}

这是我得到的明显错误,因为我不知道如何更改此自定义名称:keyNotFound(Testapp.MyModel.(CodingKeys in _7A951077E4B6EF2E56D367C5DE0BF0AC).customName, Swift.DecodingError.Context(codingPath: [], debugDescription: "Cannot get KeyedDecodingContainer<GenericCodingKeys> -- no value found for key \"customName\"", underlyingError: nil))

【问题讨论】:

    标签: json swift swift4


    【解决方案1】:

    如果您已经知道内部 JSON 中的所有键,请使用结构来利用静态类型。假设您的 JSON 的顶层只有 1 个键(您的 customName 键):

    struct MyModel: Decodable {
        struct InnerModel: Decodable {
            var constantKey1: Double
            var constantKey2: Double
        }
    
        var customName: InnerModel
    
        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: GenericCodingKeys.self)
    
            // Assume that there's only 1 key at the top level in the JSON
            if let key = container.allKeys.first {
                customName = try container.decode(InnerModel.self, forKey: key)
            } else {
                throw NSError(domain: NSCocoaErrorDomain, code: 0, userInfo: [NSLocalizedDescriptionKey: "JSON is empty"])
            }
        }
    }
    

    【讨论】:

    • 感谢它的工作!我不知道到底是怎么回事,因为它对我来说仍然像是一种黑魔法,但我会研究这个!
    猜你喜欢
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多