我有一些REST API
,它返回JSON
。此API由不止一种服务(移动,Web等)使用,它返回的JSON
中包含的字段超出了我的需要,并且其中一些其他字段可以每周更改。
例如,我有这样的JSON:
{“名称”:“丰田普锐斯”,“马力”:134,“里程”:123241, “制成品”:2017年,“位置”:“一个城市”,“产地”:“日本”,
“ convert”:true //更多属性随即...}
在移动应用程序中,我只需要解码字段:名称,马力和制造日期,其余的可以忽略。此外,某些字段(例如起源)以前不存在,但几天前已添加。
问题是如何编写防弹解码器,如果JSON
中的某些更改不影响应用程序中的模型,该解码器不会中断?另外,我在服务器的输出JSON
中没有任何内容,也无法影响它。我只获取数据,而我必须处理得到的东西。
我已经为操场写了一些实验代码(没有打印出汽车):
import UIKit
struct Car: Codable
{
let name: String
let horsePower: Int
let selected: Bool //this is used as additional property inside my app to mark selected cars
let index: Int //this is used as additional property inside my app for some indexing purposes
enum CodingKeys: String, CodingKey
{
case name
case horsePower = "horsepower"
case selected
case index
}
init(from decoder: Decoder) throws
{
let values = try decoder.container(keyedBy: CodingKeys.self)
selected = false
index = 0
name = try values.decode(String.self, forKey: .name)
horsePower = try values.decode(Int.self, forKey: .horsePower)
}
}
let json = "{\"name\": \"Toyota Prius\",\"horsepower\": 134, \"convert\", true}"
let data = json.data(using: .utf8)
if let car = try? JSONDecoder().decode(Car.self, from: data!)
{
//does not print... :(
print(car)
}
我想在示例中打印汽车,但是大多数情况下,如果JSON
被更改,其工作证明代码不会损坏。
还有没有办法以某种方式获得解码错误描述?
我知道Apple文档中有很多内容,但是大多数情况下,这对我来说太混乱了,我找不到解决此问题的有用示例。
答案 0 :(得分:2)
首先从不 try? JSONDecoder...
,catch
始终将错误并打印出来。 DecodingErrors非常具有描述性。他们会确切告诉您哪里出了问题,甚至出了什么地方。
在您的示例中,您将获得
“给定的数据不是有效的JSON。...字符52周围的对象没有键值。”
convert\"
之后的错误逗号(而不是冒号)
要仅解码特定密钥,请相应地声明CodingKeys
并删除init
方法。 selected
和index
最有可能是可变的,因此将它们声明为具有默认值的变量。
如果后端更改JSON结构,则会收到错误消息。无论解析API如何,解码过程都会中断。
struct Car: Codable
{
let name: String
let horsePower: Int
let convert : Bool
var selected = false
var index = 0
enum CodingKeys: String, CodingKey {
case name, horsePower = "horsepower", convert
}
}
let json = """
{"name":"Toyota Prius","horsepower":134,"convert":true}
"""
let data = Data(json.utf8)
do {
let car = try JSONDecoder().decode(Car.self, from: data)
print(car)
} catch { print(error) }