Json 需要解码字典<;字符串,任意>;但是找到了一个字符串/数据

Json 需要解码字典<;字符串,任意>;但是找到了一个字符串/数据,json,struct,swift4,decodable,Json,Struct,Swift4,Decodable,我正在使用docodable协议,出现以下错误: typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [MakeApp_v2.Params.(CodingKeys in _244BBB2F32A8C5CF3DB84B0C6A94B232).config, Swift._DictionaryCodingKey(stringValue: "table", int

我正在使用docodable协议,出现以下错误:

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))
我的结构

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数据会使程序停止。我不知道我的代码要更新什么。我希望你能帮我解决这个问题,蒂亚

我只是把我的评论转换成一个更清晰的答案


问题在于
config:[String:config]?
内部
Params
结构。从JSON中可以明显看出,您的键是
config
,值是
config
type对象,而不是
Dictionary
类型。因此,将config属性更改为
config:config?

另一个注意事项:当
struct
中的属性与JSON键相同时,可以省略
CodingKeys
enum
(与
属性
struct一样)

额外注意:我在您的结构定义中看到了很多
可选的
s。请只考虑真正需要<代码>可选<代码>类型的情况。不要只是不必要地使用它们

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
属性


对不起,我的错!“我的密钥配置”的对象类型错误。改为config=[String:config?]改为config=config?要归功于@nayem

问题在于
config:[String:config]?
内部
Params
结构。从JSON中可以明显看出,您的键是
config
,值是
config
type对象,而不是
Dictionary
类型。因此,将config属性更改为
config:config?
应该可以解决问题。lol,我没有注意到这一点。也许我仍然对这件事感到不满。呵呵,谢谢@nayemmore,我的密钥是可选的,因为在我的api上我发送不同的json结构,有些密钥存在,或者存在,但值为零;有时我不把钥匙寄出去。嗨@不,我还有一个问题。基于上面的json,如何显示“config”的数据?我认为我的结构配置没有帮助。
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]?
}
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"
  }
}