4

我正在使用可编码协议,但我遇到了这个错误:

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))

这是我遇到错误的 JSON

{
  "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"
}

我的结构

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"
  }
}

获取 JSON 数据

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" }

我有 3 组 JSON 数据结构,前两组在这种结构下工作正常,但是上面的一个 JSON 数据使程序停止。我不确定我的代码要更新什么。我希望你能帮我解决这个问题,TIA!

4

2 回答 2

1

好吧,为了更清楚,我只是将我的评论转换为答案。

问题是你的config: [String: Config]?内部Params结构。从 JSON 中可以清楚地看到,您的键是config,值是Config类型对象而不是Dictionary类型。所以将配置属性更改为config: Config?.

另一个注意事项:当您的属性struct与 JSON 键相同时,您可以省略CodingKeys枚举(就像您对Properties结构所做的那样)

额外说明:optional在您的结构定义中看到了很多 s 。请仅考虑真正需要optional类型的情况。不要只是不必要地使用它们。

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]?
}

对于进一步的说明,我怀疑更多的是,你[String: Properties]?以后也会遇到你的类型的麻烦。这更像是config我怀疑的这个属性。

于 2018-03-05T07:44:42.243 回答
0
struct Params: Decodable {
  let callBackID: String, method: Int, parName: String, pageID: String?, table: String?, fields: [String: Properties]?, imageid: String?, imagetable: String?, config: 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"
  }
}

对不起这是我的错!我的关键配置的对象类型错误。而是将 config = [String: Config?] 更改为 config = Config? 归功于@nayem

于 2018-03-05T08:00:45.293 回答