struct Classroom: Codable {
let teacher: String
let id: Int
let status: Bool
init(from decoder: Decoder) throws {
...
...
}
}
現在我需要一種Classroom
使用簡單字串創建實體的方法
{ "classroom": "Test" }//從 API 接收
let classRoom = ClassRoom(teacher: "Test", id: 0, status: true)
現在我需要添加一個decoder
可以使用資料創建此classroom
實體的輔助方法"classroom": "Test"
。“Test”值應用作“teacher”的值,其他屬性應包含默認值。
我知道我可以解碼該String
值并創建一個新的初始化程式。有沒有辦法直接解碼String
到這個模型物件?
uj5u.com熱心網友回復:
如果我理解得很好,我假設您的 json 格式不正確,如下所示
[
{
"teacher":"test",
"id":5,
"status":true
},
{
"classroom":"Test"
}
]
并且您想解碼這兩個物件,您可以執行以下操作
let data = """
[
{
"teacher": "test",
"id": 5,
"status": true
},
{
"classroom": "Test"
}
]
""".data(using: .utf8)!
struct Classroom: Codable {
let teacher: String
let id: Int
let status: Bool
private enum CodingKeys: CodingKey {
case teacher, id, status
}
private enum SecCodingKeys: CodingKey {
case classroom
}
init(from decoder: Decoder) throws {
let value = try decoder.container(keyedBy: CodingKeys.self)
let secValue = try decoder.container(keyedBy: SecCodingKeys.self)
let teacher_1 = try value.decodeIfPresent(String.self, forKey: .teacher)
let teacher_2 = try secValue.decodeIfPresent(String.self, forKey: .classroom)
teacher = teacher_1 ?? teacher_2 ?? ""
id = try value.decodeIfPresent(Int.self, forKey: .id) ?? 0
status = try value.decodeIfPresent(Bool.self, forKey: .status) ?? false
}
}
do {
let rooms = try JSONDecoder().decode([Classroom].self, from: data)
print(rooms.map(\.teacher))
} catch {
print(error)
}
結果,
["test", "Test"]
uj5u.com熱心網友回復:
將第二個嵌套案例解碼為另一種型別
struct SimpleClassroom: Decodable {
let classroom: String
}
然后有一個計算屬性,用于映射到具有默認值的原始型別
extension SimpleClassroom {
var classroomValue: Classroom {
Classroom(teacher: classroom, id: 0, status: false)
}
}
uj5u.com熱心網友回復:
如果"Test"
是對教室的有效描述,并且您想繼續創建教室,那么您有多種選擇。
如果您知道來自給定 API 端點的教室將始終采用這種字串格式,您可以使用解碼器的背景關系字典預先告訴它使用哪種策略來解碼教室。如果有時教室是一個格式正確的字典,而有時它只是一個字串,并且您想以任何一種方式繼續,那么您必須在init(from:)
.
無論哪種方式,您都在查看自定義的 init 方法。處理這兩種型別的第二種情況如下所示:
init(from decoder: Decoder) throws {
// Do we have a single-value container?
do {
let container = try decoder.singleValueContainer()
let string = try container.decode(String.self)
self.teacher = string
self.id = 0
self.status = true
return
} catch {
// OK, it was a dictionary
}
let container = try decoder.container(keyedBy: CodingKeys.self)
self.teacher = try container.decode(String.self, forKey: .teacher)
self.id = try container.decode(Int.self, forKey: .id)
self.status = try container.decode(Bool.self, forKey: .status)
}
鑒于這個虛構的、可怕的 JSON:
[
"Test",
{ "teacher": "Mr Chips", "id": 0, "status": true }
]
let rooms = try JSONDecoder().decode([Classroom].self, from: data)
Classroom
為您提供陣列中的兩種有效型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/468894.html
上一篇:資料結構句柄為陣列