简体   繁体   中英

Swift4 Decoding a dictionary in a json schema

I'm trying to decode a json-schema to represent it's contents in swift objects. In the end, The plan is to generate swift model files. But first decoding the schema.

I can decode the 'properties' dict in the schema just fine. But when I try and decode the 'items' dictionary in a property, I get an unexpected problem:

"Expected to decode Dictionary but found a string/data instead."

If I comment out the line 30 & 35 to prevent items to be decoded, I get a success. So what's the difference between my JSONSchema.properties struct vs my Property.items struct ?

Where do I go wrong?

My code:

import Foundation

enum ObjectType: String, Decodable {
    case ObjectType = "object"
    case ArrayType = "array"
    case StringType = "string"
    case IntegerType = "integer"
    case NumberType = "number"
    case BooleanType = "boolean"
    case NullType = "null"
}

struct JSONSchema : Decodable {
    let schema: String?
    let id: String?
    let properties: Dictionary<String, Property>?

    enum CodingKeys : String, CodingKey {
        case schema = "$schema"
        case id
        case properties
    }
}

struct Property : Decodable {
    let id: String?
    let items: Dictionary<String, Item>?
    let type: ObjectType?

    enum CodingKeys : String, CodingKey {
        case id
        case items
        case type
    }
}

struct Item : Decodable {
    let id: String?
//  let properties: Dictionary<String, Property>?
//  let type: ObjectType?

    enum CodingKeys : String, CodingKey {
        case id
//      case properties
//      case type
    }
}

let jsonString = """
{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "definitions": {},
  "id": "http://example.com/example.json",
  "properties": {
    "cabinStatistics": {
      "id": "/properties/cabinStatistics",
      "items": {
        "id": "/properties/cabinStatistics/items",
        "properties": {
          "cabinClass": {
            "default": "C",
            "description": "An explanation about the purpose of this instance.",
            "examples": [
              "C",
              "M"
            ],
            "id": "/properties/cabinStatistics/items/properties/cabinClass",
            "title": "The cabinclass schema.",
            "type": "string"
          },
          "count": {
            "default": 29,
            "description": "An explanation about the purpose of this instance.",
            "examples": [
              "29"
            ],
            "id": "/properties/cabinStatistics/items/properties/count",
            "title": "The count schema.",
            "type": "integer"
          },
          "specificities": {
            "id": "/properties/cabinStatistics/items/properties/specificities",
            "items": {
              "id": "/properties/cabinStatistics/items/properties/specificities/items",
              "properties": {
                "code": {
                  "default": "ACCEPTED",
                  "description": "An explanation about the purpose of this instance.",
                  "examples": [
                    "ACCEPTED"
                  ],
                  "id": "/properties/cabinStatistics/items/properties/specificities/items/properties/code",
                  "title": "The code schema.",
                  "type": "string"
                },
                "count": {
                  "default": 21,
                  "description": "An explanation about the purpose of this instance.",
                  "examples": [
                    "21"
                  ],
                  "id": "/properties/cabinStatistics/items/properties/specificities/items/properties/count",
                  "title": "The count schema.",
                  "type": "integer"
                }
              },
              "type": "object"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "type": "array"
    }},
  "type": "object"
}
"""

if let jsonData = jsonString.data(using: .utf8) {
    do {
        let jsonSchema = try JSONDecoder().decode(JSONSchema.self, from: jsonData)
        print(jsonSchema)
        print("Success !!")
    }
    catch {
        print(error)
        print("Bummer ...")
    }
}

A JSON dictionary is decoded directly into the struct

You need to write

struct Property : Decodable {
   let id: String?
   let items : Item?
   let type: ObjectType? 
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM