Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decoding JSON with element named self

In Swift 5.1 I want to decode a JSON document containing an element named self. It is a HAL document, so I cannot change the element name.

The JSON is like this;

{
  "_embedded": {
    "eventList": [
      {
        "id": 1,
        "datetime": "2020-04-20T20:00:00",
        "description": "...",
        "_links": {
          "self": {
            "href": "http://.../events/1"
          }
        }
      },
      {
        "id": 2,
        "datetime": "2020-04-19T08:30:00",
        "description": "...",
        "_links": {
          "self": {
            "href": "http://.../events/2"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href": "http://.../events"
    }
  }
}

My domain model looks like this

struct JSonRootElement: Codable {
    var _embedded: JsonEmbedded
}

struct JsonEmbedded: Codable {
    var eventList: [JsonEvent]
}

struct JsonEvent: Codable {
    var id: Int
    var datetime: String
    var description: String
    var _links: JsonHalLink
}

struct JsonHalLink: Codable {
    var self: JsonHalSelfLink
}

struct JsonHalSelfLink: Codable {
    var href: String
}

Of course, the JsonHalLink struct contains a forbidden name. I can rename the variable name, but how to tell Swift it has to read the self element from JSON?

like image 471
Marc Enschede Avatar asked Nov 13 '19 17:11

Marc Enschede


1 Answers

You can use back-ticks (`) around restricted keywords to use them as variable names.

struct JsonHalLink: Codable {
    let `self`: JsonHalSelfLink
}

Otherwise, if you want your variable to have a different name than its JSON key, you can declare a CodingKey conformant enum to define a mapping between your property names and JSON keys.

struct JsonHalLink: Codable {
    let varName: JsonHalSelfLink

    private enum CodingKeys: String, CodingKey {
        case varName = "self"
    }
}

Unrelated to your question, but you should only declare properties as mutable (var) when they actually need to be mutable. If they are never mutated, simply declare them as immutable (let).

like image 148
Dávid Pásztor Avatar answered Oct 25 '22 16:10

Dávid Pásztor