【发布时间】:2018-08-14 09:00:37
【问题描述】:
我已经为此苦苦挣扎了一段时间。我有一个从 API 调用中获得的 JSON,但它有一个键,如果它是真的,它可以是假的或者返回一个值。
像这样:
{
"id": 550,
"favorite": true,
"rated": {
"value": 8
},
"watchlist": false
}
或者这个:
{
"id": 550,
"favorite": true,
"rated": false,
"watchlist": false
}
我试着这样解码:
struct AccountState: Decodable {
var id: Int?
var favorite: Bool?
var rated: CustomValue
var watchlist: Bool?
}
struct RatingValue: Decodable {
var value: Double?
}
enum CustomValue: Decodable {
case bool(Bool)
case rating(RatingValue)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let bool = try? container.decode(Bool.self) {
self = .bool(bool)
} else if let rating = try? container.decode(RatingValue.self) {
self = .rating(rating)
} else {
let context = DecodingError.Context(codingPath: container.codingPath, debugDescription: "Unknown type")
throw DecodingError.dataCorrupted(context)
}
}
}
在 ViewController 中:
func dowloadAndDecodeData() {
let url...
...
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
guard let accountState = try? decoder.decode(AccountState.self, from: data) else {
print("error")
return
}
print(accountState)
}
在控制台中,我可以看到 JSON 内容已正确解析(如果存在则返回 false 或 value)。
问题是:如何从代码中访问该值?由于“rated”是“CustomValue”类型,我不能像通常使用的那样只做accountState.rated.value。
【问题讨论】: