Search code examples
jsonswiftcodabledecodableencodable

How to encode a dictionary of unknown/variable keys?


Say I have to send this data to the server:

struct Event: Codable {
    let title: String
    let params: [String:Any]? //Not allowed
}

So for instance, these events could look like any of these:

let event = Event(title: "cat was pet", params:["age": 7.2])
let event = Event(title: "cat purred", params:["time": 9])
let event = Event(title: "cat drank", params:["water": "salty", "amount": 3.3])

I need the ability to send any arbitrary amount of key/value pairs as params to the event. Is this even possible with Codable? If not, how would I encode params as a json string?


Solution

  • Codable is magic if all types conform to Codable, but in your case I suggest traditional JSONSerialization. Add a computed property dictionaryRepresentation

    struct Event: {
        let title: String
        let params: [String:Any]
    
        var dictionaryRepresentation: [String:Any] {
            return ["title":title,"params":params] 
        }
    }
    

    then encode the event

    let data = try JSONSerialization.data(withJSONObject: event.dictionaryRepresentation)
    

    This is less expensive/cumbersome than forcing Any to become Codable (no offense, Rob).