我目前退回Auto-Renewable
和Non-Renewable
的收据。但是Non-Renewable
并没有返回expires_date
json键。我怎么能忽略这一点。我试图避免将expires_date
设为可选。当我将其设置为可选时,Apple会发送回响应。有没有办法我可以解码json而无需将expires_date
设为可选。
struct Receipt: Codable {
let expiresDate: String
private enum CodingKeys: String, CodingKey {
case expiresDate = "expires_date"
}
}
现在我可以得到
“没有与键CodingKeys相关联的值(字符串值:\“ expires_date \”,整数值:nil)(\“ expires_date \”)。“
答案 0 :(得分:4)
您将必须实现自己的init(from: Decoder)
并使用decodeIfPresent(_:forKey:)
,然后再将其零合并为默认值。
struct Receipt: Codable {
let expiresDate: String
enum CodingKeys: String, CodingKey {
case expiresDate = "expires_date"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.expiresDate = try values.decodeIfPresent(String.self, forKey: .expiresDate)
?? "1970" //Default value
}
}
注意:
Receipt
具有更多的键值对,那么您也必须手动对其进行解码。let data = """
[{
"expires_date": "2019"
},
{
}]
""".data(using: .utf8)!
do {
let obj = try JSONDecoder().decode([Receipt].self, from: data)
print(obj)
}
catch {
print(error)
}
答案 1 :(得分:3)
如何对其进行手动解码:
struct Receipt: Codable {
let expiresDate: String
private enum CodingKeys: String, CodingKey {
case expiresDate = "expires_date"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
if let expDate = try? values.decode(String.self, forKey: .expiresDate) {
self.expiresDate = expDate
} else {
self.expiresDate = "sth"
}
}
}
示例:
struct Receipt: Codable {
let expiresDate: String
let b: String
private enum CodingKeys: String, CodingKey {
case expiresDate = "expires_date"
case b = "b"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
if let expDate = try? values.decode(String.self, forKey: .expiresDate) {
self.expiresDate = expDate
} else {
self.expiresDate = "sth"
}
b = try values.decode(String.self, forKey: .b)
}
}
let a = """
{
"b": "asdf"
}
""".data(using: .utf8)!
let myStruct = try JSONDecoder().decode(Receipt.self, from: a)
print(myStruct) //Receipt(expiresDate: "sth", b: "asdf")