【问题标题】:How to encode a property with type of JSON dictionary in Swift 4 encodable protocol如何在 Swift 4 可编码协议中使用 JSON 字典类型对属性进行编码
【发布时间】:2018-05-14 11:48:04
【问题描述】:

嗯,我的问题很简单。我想做与此答案相同的操作,但要进行编码: How to decode a property with type of JSON dictionary in Swift 4 decodable protocol

该解决方案适用于解码,但我还需要编码 Dictionary<String, Any>

我不知道如何为KeyedEncodingContainer 和其他扩展编写扩展,以及编写什么方法。

【问题讨论】:

    标签: ios json swift codable decodable


    【解决方案1】:

    您可以通过修改该问题答案中的可解码代码 sn-p 来做到这一点

    extension KeyedEncodingContainerProtocol where Key == JSONCodingKeys {
        mutating func encodeJSONDictionary(_ value: Dictionary<String, Any>) throws {
            try value.forEach({ (key, value) in
                let key = JSONCodingKeys(key: key)
                switch value {
                case let value as Bool:
                    try encode(value, forKey: key)
                case let value as Int:
                    try encode(value, forKey: key)
                case let value as String:
                    try encode(value, forKey: key)
                case let value as Double:
                    try encode(value, forKey: key)
                case let value as Dictionary<String, Any>:
                    try encode(value, forKey: key)
                case let value as Array<Any>:
                    try encode(value, forKey: key)
                case Optional<Any>.none:
                    try encodeNil(forKey: key)
                default:
                    throw EncodingError.invalidValue(value, EncodingError.Context(codingPath: codingPath + [key], debugDescription: "Invalid JSON value"))
                }
            })
        }
    }
    
    extension KeyedEncodingContainerProtocol {
        mutating func encode(_ value: Dictionary<String, Any>, forKey key: Key) throws {
            var container = self.nestedContainer(keyedBy: JSONCodingKeys.self, forKey: key)
            try container.encodeJSONDictionary(value)
        }
    
        mutating func encodeIfPresent(_ value: Dictionary<String, Any>?, forKey key: Key) throws {
            if let value = value {
                try encode(value, forKey: key)
            }
        }
    
        mutating func encode(_ value: Array<Any>, forKey key: Key) throws {
            var container = self.nestedUnkeyedContainer(forKey: key)
            try container.encodeJSONArray(value)
        }
    
        mutating func encodeIfPresent(_ value: Array<Any>?, forKey key: Key) throws {
            if let value = value {
                try encode(value, forKey: key)
            }
        }
    }
    
    extension UnkeyedEncodingContainer {
        mutating func encodeJSONArray(_ value: Array<Any>) throws {
            try value.enumerated().forEach({ (index, value) in
                switch value {
                case let value as Bool:
                    try encode(value)
                case let value as Int:
                    try encode(value)
                case let value as String:
                    try encode(value)
                case let value as Double:
                    try encode(value)
                case let value as Dictionary<String, Any>:
                    try encode(value)
                case let value as Array<Any>:
                    try encode(value)
                case Optional<Any>.none:
                    try encodeNil()
                default:
                    let keys = JSONCodingKeys(intValue: index).map({ [ $0 ] }) ?? []
                    throw EncodingError.invalidValue(value, EncodingError.Context(codingPath: codingPath + keys, debugDescription: "Invalid JSON value"))
                }
            })
        }
    
        mutating func encodeJSONDictionary(_ value: Dictionary<String, Any>) throws {
            var nestedContainer = self.nestedContainer(keyedBy: JSONCodingKeys.self)
            try nestedContainer.encodeJSONDictionary(value)
        }
    }
    

    这是一个代码sn-p

    但是,这段代码 sn-p 在 Swift 4.1 中会失败,应该在 2018 年上半年发布。

    【讨论】:

    • 非常感谢!我会试试看的!
    • @MauroTaroco 我希望我的回答还不算太晚:P
    • 呵呵,好吧,有点。但这没问题,永远不会太晚,我会在下一个项目中尝试!谢谢!!!
    • @MauroTaroco 我已经修复了 swift 4.1,但它没有经过 100% 测试github.com/3D4Medical/gltf_scenekit/blob/master/Sources/…
    • @SAKrisT 太棒了!!也将在下一个项目中尝试!感谢分享!
    猜你喜欢
    • 2017-11-20
    • 2018-05-14
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 2018-03-31
    • 2021-10-30
    • 2020-10-19
    相关资源
    最近更新 更多