With JSONDecoder in Swift 4, can missing keys use a default value instead of having to be optional properties?(使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗?)
问题描述
Swift 4 添加了新的 Codable
协议.当我使用 JSONDecoder
时,它似乎要求我的 Codable
类的所有非可选属性在 JSON 中有键,否则会引发错误.
Swift 4 added the new Codable
protocol. When I use JSONDecoder
it seems to require all the non-optional properties of my Codable
class to have keys in the JSON or it throws an error.
让我的类的每个属性都是可选的似乎是不必要的麻烦,因为我真正想要的是使用 json 中的值或默认值.(我不希望该属性为零.)
Making every property of my class optional seems like an unnecessary hassle since what I really want is to use the value in the json or a default value. (I don't want the property to be nil.)
有没有办法做到这一点?
Is there a way to do this?
class MyCodable: Codable {
var name: String = "Default Appleseed"
}
func load(input: String) {
do {
if let data = input.data(using: .utf8) {
let result = try JSONDecoder().decode(MyCodable.self, from: data)
print("name: (result.name)")
}
} catch {
print("error: (error)")
// `Error message: "Key not found when expecting non-optional type
// String for coding key "name""`
}
}
let goodInput = "{"name": "Jonny Appleseed" }"
let badInput = "{}"
load(input: goodInput) // works, `name` is Jonny Applessed
load(input: badInput) // breaks, `name` required since property is non-optional
推荐答案
我更喜欢的方法是使用所谓的 DTO - 数据传输对象.它是一个结构,符合 Codable 并表示所需的对象.
Approach that I prefer is using so called DTOs - data transfer object. It is a struct, that conforms to Codable and represents the desired object.
struct MyClassDTO: Codable {
let items: [String]?
let otherVar: Int?
}
然后,您只需使用该 DTO 初始化您想在应用程序中使用的对象.
Then you simply init the object that you want to use in the app with that DTO.
class MyClass {
let items: [String]
var otherVar = 3
init(_ dto: MyClassDTO) {
items = dto.items ?? [String]()
otherVar = dto.otherVar ?? 3
}
var dto: MyClassDTO {
return MyClassDTO(items: items, otherVar: otherVar)
}
}
这种方法也很好,因为您可以根据需要重命名和更改最终对象.与手动解码相比,它很清晰并且需要更少的代码.此外,通过这种方法,您可以将网络层与其他应用程序分开.
This approach is also good since you can rename and change final object however you wish to. It is clear and requires less code than manual decoding. Moreover, with this approach you can separate networking layer from other app.
这篇关于使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!