Sarath  Kumar Rajendran
Sarath Kumar Rajendran

Reputation: 426

How can I use [String: Any]? as property in Struct which conforms to 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

Upvotes: 13

Views: 8673

Answers (1)

Josh Homann
Josh Homann

Reputation: 16327

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

Upvotes: 13

Related Questions