本文介绍了Swift Codable多种类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我尝试解析返回json对象的api。我的问题是,某些键有时是字符串,有时是诸如以下示例中的键 Value之类的对象:
I try to parse an api returning a json object. My problem is that some keys are sometime a string, sometime an object like the key "Value" in the following example:
[
{
"Description": null,
"Group": "Beskrivning av enheten",
"GroupDescription": null,
"Id": "Description",
"Name": "Mer om enheten",
"Value": "Det finns möjlighet till parkering på gatorna runt om, men det är kantstenar och ganska branta backar för att komma upp till lekplatsen.\r\n\r\nUtanför själva lekplatsen finns en gungställning med en plan omväg in. Alla lekredskap står i sandytor, det finns många kanter. Runt hela lekplatsen går ett staket med öppningar i olika riktningar."
},
{
"Description": null,
"Group": "Bilder och film",
"GroupDescription": null,
"Id": "Image",
"Name": "Huvudbild",
"Value": {
"__type": "FileInfo",
"Id": "8871b3b1-14f4-4054-8728-636d9da21ace",
"Name": "ullerudsbacken.jpg"
}
}
]
我的结构如下:
struct ServiceUnit: Codable {
let description: String?
let group: String?
let groupDescription: String?
let id: String
let name: String
var value: String?
struct ServiceUnitTypeInfo: Codable {
let id: String
let singularName: String?
enum CodingKeys: String, CodingKey {
case id = "Id"
case singularName = "SingularName"
}
}
let serviceUnitTypeInfo: ServiceUnitTypeInfo?
let values: [String]?
enum CodingKeys: String, CodingKey {
case description = "Description"
case group = "Group"
case groupDescription = "GroupDescription"
case id = "Id"
case name = "Name"
case value = "Value"
case serviceUnitTypeInfo = "ServiceUnitTypeInfo"
case values = "Values"
case image = "Image"
}
}
我必须设法确保我完全迷失了(是的,我是个快速入门的人),我找不到解决问题的方法。我了解我必须使用自定义init,但我不知道如何使用。
I have to admin that I am totally lost (yes, I am a beginner in swift) and I can't find a solution to my problem. I understand that I have to use a custom init, but I don't know how.
推荐答案
您可以尝试
struct Root: Codable {
let description,id: String
let group,groupDescription: String?
let name: String
let value: MyValue
enum CodingKeys: String, CodingKey {
case description = "Description"
case group = "Group"
case groupDescription = "GroupDescription"
case id = "Id"
case name = "Name"
case value = "Value"
}
}
enum MyValue: Codable {
case string(String)
case innerItem(InnerItem)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
if let x = try? container.decode(InnerItem.self) {
self = .innerItem(x)
return
}
throw DecodingError.typeMismatch(MyValue.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for MyValue"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let x):
try container.encode(x)
case .innerItem(let x):
try container.encode(x)
}
}
}
struct InnerItem: Codable {
let type, id, name: String
enum CodingKeys: String, CodingKey {
case type = "__type"
case id = "Id"
case name = "Name"
}
}
do {
let result = try JSONDecoder().decode([Root].self,from:data)
print(result)
}
catch {
print(error)
}
这篇关于Swift Codable多种类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!