0

I am trying decode a JSON with below structure and convert to a Swift struct object.

"{\"createdAt\":\"2021-07-20T06:53:05.755Z\",\"extraPayload\":\"32bd7d6691964519\",\"messageID\":\"a5f77d0a27da2e14a78ce4d736590bb3c369d5e5bebd36339553e3b699b82d13\",\"publishedAt\":\"2021-07-20T06:53:05.836655Z\"}"

Both the publishedAt and messageID fields are fixed and any other fields in the JSON can be arbitrary based on a particular use-case. In this case both fields createdAt and extraPayload are completely optional and another case it could be something like appConfig:true etc apart from the 2 fixed fields.

How can I map into a struct with below format which has 2 mandatory fixed fields and arbitrary part captured using a Dictionary of type [String:Any]?

public struct MessagePayload {
    /**
     * Message identifier — opaque non-empty string.
     */
    let messageID: String
    
    /**
     * ISO 8601 date indicating a moment when the message was published to the ACN back-end service.
     */
    let publishedAt: String
    
    /**
     * Application-specific fields.
     */
    let messageObject: [String:Any]?
}

I have tried using Swift Codable but it does not support [String:Any].

HariJustForFun
  • 521
  • 2
  • 8
  • 17
  • Make them Optional. The word 'below' is not an adjective. – El Tomato Jul 20 '21 at 07:22
  • I have tried Optional. Dictionary does not get mapped. – HariJustForFun Jul 20 '21 at 07:24
  • @HariJustForFun You need to be more explicit. What are the different possibilities for `messageObject`? If you can share atleast 2 styles (in json examples) then we can help you explore the world of [Custom Decoders](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types). – staticVoidMan Jul 20 '21 at 07:25
  • Thanks staticVoidMan. Updated the question. Please let me know if it's clearer. – HariJustForFun Jul 20 '21 at 07:29
  • Anothere duplicate of https://stackoverflow.com/questions/68254792/swift-decode-json-response-and-store-nested-json-as-string-or-json ? – Sulthan Jul 20 '21 at 07:32
  • Use a custom Codable decoder for the fixed fields, and SwiftyJSON for the other fields that you want to use as an untyped dictionary. – Damiaan Dufaux Jul 20 '21 at 09:25

1 Answers1

2

It seems like JSONSerialization from Foundation is probably a better fit for your use case. This will decode the JSON data directly into an Any type, which you can then cast to [String: Any] to access the underlying properties.

let decoded = try? JSONSerialization.jsonObject(with: myJsonData, options: []) as? [String: Any]
decoded?["messageID"]
decoded?["publishedAt"]
// ...access other properties as needed
Bradley Mackey
  • 6,777
  • 5
  • 31
  • 45