Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expected to decode Dictionary<String, Any> but found a string/data instead

I'm working with the docodable protocol and I'm having this error:

typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [MakeApp_v2.Params.(CodingKeys in _244BBB2F32A8C5CF3DB84B0C6A94B232).config, Swift._DictionaryCodingKey(stringValue: "table", intValue: nil)], debugDescription: "Expected to decode Dictionary<String, Any> but found a string/data instead.", underlyingError: nil))

Here's the JSON that I encouter an error

{
  "callBackID" : "add1867f-6005-189c-bbb4-ff53202b0697",
  "config" : {
    "description" : "Welcome Page",
    "show-bottom-bar" : "",
    "css-page-align" : "",
    "footer" : { "show" : "", "object" : "bottom-bar" },
    "pageStyle" : "full-page",
    "sourceType" : "list",
    "title" : "Welcome Page",
    "header" : { "show" : true, "hide" : false, "object" : "top-bar" },
    "columns" : {},
    "objects" : {},
    "showtabs" : true,
    "slides" : [{"title" : "first section","map" : ["open"]}],
    "table" : "",
    "show-top-bar" : true,
    "style_max-width" : "",
    "slideType" : "slide"
  },
  "method" : 106,
  "parName" : "A1519614709427",
  "formid" : "1"
}

My struct

struct Params: Decodable {
  let callBackID: String, method: Int, parName: String, pageID: String?, table: String?, fields: [String: Properties]?, imageid: String?, imagetable: String?, config: [String: Config]?, appTemplate: String?, appName: String?, values: Properties?, columns: [String: Properties]?, filter: [String: Properties]?

  private enum CodingKeys: String, CodingKey {
    case callBackID = "callBackID", method = "method", parName = "parName", pageID = "pageID", table = "table", fields = "fields", imageid = "imageid", imagetable = "imagetable", config = "config", appTemplate = "appTemplate", appName = "appName", values = "values", columns = "columns", filter = "filter"
  }
}

struct Properties: Decodable {
  let source: String?, type: String?, rec_id: String?, name: String?, value: String?
}

struct Config: Decodable {
  let table: String?

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

Getting the JSON data

var param: Params?
do {
    let jsonData = try JSONSerialization.data(withJSONObject: message.body, options: .prettyPrinted)
    print(String(data: jsonData, encoding: .utf8)!)
    param = try JSONDecoder().decode(Params.self, from: jsonData)
    print(param!)
} catch {
    print(error)
}
methods(param: param!)
print(methods)
}

func methods(param: Params) -> String { return "some string" }

I have 3 sets of JSON data structure, the first two sets are working fine with this structure, but the one JSON data above make the program stop. Im not sure what to update on my code. I hope you can help me to resolve this problem, TIA!

like image 427
riogarrell Avatar asked Aug 11 '26 01:08

riogarrell


1 Answers

Well I'm just converting my comment into an answer for more clarity.

The problem is your config: [String: Config]? inside Params structure. From the JSON, it's clearly noticeable that your key is config and the value would be a Config type object not the Dictionary type. So change the config property to config: Config?.

Another note: when the properties in your struct are same as the JSON keys, you can omit the CodingKeys enum (as like you did with your Properties struct)

Extra note: I'm seeing a lot of optionals in your struct definitions. Please consider only the cases when you really need the optional types. Don't just use them unnecessarily.

struct Params: Decodable {
    let callBackID: String
    let method: Int
    let parName: String
    let pageID: String?
    let table: String?
    let fields: [String: Properties]?
    let imageid: String?
    let imagetable: String?
    let config: Config?
    let appTemplate: String?
    let appName: String?
    let values: Properties?
    let columns: [String: Properties]?
    let filter: [String: Properties]?
}

For further notes, what I suspect more is, you will also get in troubles with your [String: Properties]? types later. It's more like this config property I suspect.

like image 117
nayem Avatar answered Aug 12 '26 18:08

nayem