json - Swift 4错误序列化json typeMismatch
问题描述
我正在尝试将数据从静态 JSON 文件解析到我的实体,但出现以下错误:Error serializing json typeMismatch
这个想法是创建一个公式集合应用程序。每次通过加载 JSON 启动应用程序时,都应加载公式集合。这样更容易更新公式列表。
我猜 JSON 解释了预期的数据结构。
我的 JSON:
[
{
"category_name": "Wasserbau",
"icon": "wave",
"formula_list": [
{
"formula_name": "Formel 1",
"formula_description": "Demo Formel für Testat",
"formula": "x=y/z",
"favorite": false
},
{
"formula_name": "Formel 2",
"formula_description": "Demo Formel für Testat",
"formula": "x=y/z",
"favorite": false
}
]
},
{
"category_name": "Strassenbau",
"icon": "wave",
"formula_list": [
{
"formula_name": "Formel 3",
"formula_description": "Demo Formel für Testat",
"formula": "x=y/z",
"favorite": false
},
{
"formula_name": "Formel 4",
"formula_description": "Demo Formel für Testat",
"formula": "x=y/z",
"favorite": false
}
]
},
{
"category_name": "Hochbau",
"icon": "wave",
"formula_list": [
{
"formula_name": "Formel 5",
"formula_description": "Demo Formel für Testat",
"formula": "x=y/z",
"favorite": false
},
{
"formula_name": "Formel 6",
"formula_description": "Demo Formel für Testat",
"formula": "x=y/z",
"favorite": false
}
]
}
]
我尝试解析 JSON 的函数:
func loadCategoryJSONData() {
let jsonUrlString = "https://joshuahemmings.ch/data.json"
guard let url = URL(string: jsonUrlString) else {return} //
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else {return}
print("JSON Response: ")
print(data)
do {
let categoryJSONData = try JSONDecoder().decode(CategoryList.self, from: data)
for category in categoryJSONData.data {
print(category.categoryName)
}
} catch let jsonErr {
print("Error serializing json", jsonErr)
}
}.resume()
}
我的实体:
struct CategoryList: Decodable {
let data: [Category]
}
struct Formula: Codable {
let formulaName : String
let formulaDescription : String
let formula : String
let favorite: Bool
enum CodingKeys: String, CodingKey {
case formulaName = "formula_name"
case formulaDescription = "formula_description"
case formula
case favorite
}
init(_ dictionary: [String: Any]) {
self.formulaName = dictionary["formulaName"] as? String ?? ""
self.formulaDescription = dictionary["formulaDescription"] as? String ?? ""
self.formula = dictionary["formula"] as? String ?? ""
self.favorite = dictionary["favorite"] as? Bool ?? false
}
}
struct Category: Codable {
let categoryName: String
let icon: String
let formulaList: [Formula]
enum CodingKeys: String, CodingKey {
case categoryName = "category_name"
case icon = "icon"
case formulaList = "formula_list"
}
init(_ dictionary: [String: Any]) {
self.categoryName = dictionary["categoryName"] as? String ?? ""
self.icon = dictionary["icon"] as? String ?? ""
self.formulaList = dictionary["formulaList"] as? [Formula] ?? []
}
}
解决方案
您的主要问题是声明类型来解析 this JSON
。
你没有在CategoryList
这里,它会是这样的:
{
"data": [ … <Category JSON> … ]
}
你刚刚[Category]
在这里,就像 JSON 根是Array
( []
),而不是Object
( {}
)。
所以而不是
try decoder.decode(CategoryList.self, from: data)
你应该做
try decoder.decode([Category].self, from: data)
此外,如果您的编码键与 JSON 中的键几乎相同,但不是在蛇案例中,则不应CodingKey
为您的类型声明自定义。请改用正确的.keyDecodingStrategy。
struct Formula: Codable {
let formulaName: String
let formulaDescription: String
let formula: String
let favorite: Bool
}
struct Category: Codable {
let categoryName: String
let icon: String
let formulaList: [Formula]
}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let categoryJSONData = try decoder.decode([Category].self, from: data)
推荐阅读
- amazon-web-services - 查找以假定角色调用我的 lambda 的帐户
- rust - 无法改变包含在静态 Lazy 中的变量
> 因为它的寿命不够长 - reactjs - setInterval 异常行为
- angular - REST web 服务可以返回异常吗?
- android - LastLocation 未在第一次更新
- c# - 寻找有关存储用户偏好的最佳实践的建议
- symfony4 - 如何在 CoreShop 多个商店中向客户登录检查添加自定义验证逻辑
- puppet - 正整数的木偶数组
- javascript - 将带有 connectNative 的变量传递到 Javascript 文件(Chrome 扩展程序)
- angular - Angular - 如何自动触发 mat-error