swiftswift4codable

How can I use Swift’s Codable to encode into a dictionary?


I have a struct that implements Swift 4’s Codable. Is there a simple built-in way to encode that struct into a dictionary?

let struct = Foo(a: 1, b: 2)
let dict = something(struct)
// now dict is ["a": 1, "b": 2]

Solution

  • If you don't mind a bit of shifting of data around you could use something like this:

    extension Encodable {
      func asDictionary() throws -> [String: Any] {
        let data = try JSONEncoder().encode(self)
        guard let dictionary = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] else {
          throw NSError()
        }
        return dictionary
      }
    }
    

    Or an optional variant (syntax fix for 2024)

    extension Encodable {
      var dictionary: [String: Any]? {
        guard let data = try? JSONEncoder().encode(self) else { return nil }
        return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)).flatMap { $0 as? [String: Any] }
      }
    }
    

    Assuming Foo conforms to Codable or really Encodable then you can do this.

    let struct = Foo(a: 1, b: 2)
    let dict = try struct.asDictionary()
    let optionalDict = struct.dictionary
    

    If you want to go the other way(init(any)), take a look at this Init an object conforming to Codable with a dictionary/array