Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use [String: Any]? as property in Struct which conforms to Codable

Tags:

swift

codable

I am having a struct which conforms to the protocol Codable. I am having a property of type [String: Any]?. But the codable doesn't allow me to use it. Saying the error

does not conform to protocol 'Decodable

like image 501
Sarath Kumar Rajendran Avatar asked Apr 19 '19 15:04

Sarath Kumar Rajendran


1 Answers

Use the old JSONSerialization class to convert between Data and [String: Any] if you must. Data is Codable. You could also use another format, just as String. Note that swift is strongly typed, so using an enum with associated values is generally preferred over Any. If the intent is to actually write to the sever and not to local storage then you can also consider just forgetting about Codable and using JSONSerialization for the whole thing.

Example:

import UIKit
import PlaygroundSupport

struct A: Codable {
    let a: Int
    let b: [String: Any]

    enum CodingKeys: String, CodingKey {
        case a
        case b
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        a = try values.decode(Int.self, forKey: .a)
        let data = try values.decode(Data.self, forKey: .b)
        b = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(a, forKey: .a)
        let data = try JSONSerialization.data(withJSONObject: b, options: [])
        try container.encode(data, forKey: .b)
    }
}
like image 173
Josh Homann Avatar answered Oct 09 '22 01:10

Josh Homann