有没有办法使用带有注入属性的Decodable?
final class Score: Decodable {
let value: Int?
let uniqueId: String
convenience init(from decoder: Decoder/*, uniqueId: String*/) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
try container.decodeIfPresent(Int.self, forKey: .value).flatMap { value = $0 }
// self.uniqueId = uniqueId
[... other properties parsing ...]
}
}示例调用:
final class Exam {
let identifier: Int
let scores: [Score]
convenience init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
identifier = try container.decode(Int.self, forKey: .identifier)
scores = try container.decode([Score].self, forKey: .scores)
// I need to pass Exam's identifier to `score` on init, because it will generate Score's `uniqueId `
[... other properties parsing ...]
}
}这将以缺少uniqueId的错误结束,我需要在初始化之后拥有它,但它不在JSON中。因为它是标识符,所以将它设为可选并设置在外部不是处理它的正确方法。
我很乐意按照上面所说的方式注入它,但是该怎么做呢?
发布于 2021-03-25 19:32:35
没有办法扩展初始化器,因为它是间接调用的,并且没有提供API来扩展它。因此,有几种方法可以绕过它:
userInfo中。下面的例子。JSONSerialization代替Decodable.方法2的示例:
final class ScoreResponse: Decodable {
let value: Int?
convenience init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
try container.decodeIfPresent(Int.self, forKey: .value).flatMap { value = $0 }
[... other properties parsing ...]
}
}
final class Score {
let value: Int?
let uniqueId: String
convenience init(from response: ScoreResponse, uniqueId: String) {
self.value = response.value // etc with other properties
self.uniqueId = uniqueId
}
}
final class Exam: Decodable {
let identifier: String
let scores: [Score] = []
convenience init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
identifier = try container.decode(String.self, forKey: .identifier)
try container.decodeIfPresent([ScoreResponse].self, forKey: .scores).forEach {
scores.append({ Score(from: $0, uniqueId: identifier) })
}
}https://stackoverflow.com/questions/66782493
复制相似问题