简体   繁体   English

如何在Swift 4可编码协议中使用JSON字典类型编码属性

[英]How to encode a property with type of JSON dictionary in Swift 4 encodable protocol

Well, my question is simple. 好吧,我的问题很简单。 I want to do the same as this answer but for encode: How to decode a property with type of JSON dictionary in Swift 4 decodable protocol 我想做与此答案相同的操作,但要进行编码: 如何在Swift 4可解码协议中使用JSON字典类型解码属性

That solution works fine with decode, but I also need encode a Dictionary<String, Any> 该解决方案可以很好地与解码配合使用,但是我还需要对Dictionary<String, Any>进行编码

I can't realize how to write the extension for KeyedEncodingContainer and the other extensions, and what methods to write. 我不知道如何为KeyedEncodingContainer和其他扩展编写扩展,以及编写什么方法。

You can do that by adapting the Decodable code snippet from that question's answer 您可以通过根据问题的答案改编可解码代码段来实现

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)
    }
}

Here's a code snippet for that 这是一个代码片段

However, this code snippet will fail in Swift 4.1 which should be released within the first half of 2018. 但是,此代码段将在Swift 4.1中失败,该版本应在2018年上半年发布。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 swift 将字典转换为 jsonString 错误:协议类型 'Any' 不能符合 'Encodable' 因为只有具体类型才能符合协议 - swift Convert dictionary to jsonString error : Protocol type 'Any' cannot conform to 'Encodable' because only concrete types can conform to protocols 类型不符合“可编码”协议 - Type does not conform to protocol 'Encodable' 如何在没有密钥的 Swift 5 可解码协议中解码字典数组类型的属性? - How to decode a property with type of Array of dictionary in Swift 5 decodable protocol without key? 以协议类型为键的 Swift 字典 - Swift Dictionary with Protocol Type as Key 类型'X'不符合协议'Encodable' - Type 'X' does not conform to protocol 'Encodable' 类型“PlayerData”不符合协议“Decodable”和“Encodable” - Type 'PlayerData' does not conform to protocol 'Decodable' and 'Encodable' Swift协议 - 属性类型子类 - Swift Protocol - Property type subclass 类型“模型”不符合协议“可解码”/可编码 - Type 'Model' does not conform to protocol 'Decodable'/Encodable 类型“ MyWeather”不符合协议“可编码”错误 - Type 'MyWeather' does not conform to protocol 'Encodable' error 如何使用受限于泛型类型的属性和 Swift 中的协议初始化 class - How to initialize a class with a property that is constrained to a generic type and a protocol in Swift
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM