У меня есть struct
со свойством Double
, которое представляется как String
в JSON
, полученном из бэкэнда.
struct Test: Codable {
@StringRepresentation
var value: Double?
}
Вместо орудия init(from:)
Я создал следующую оболочку свойств, которая использует LosslessStringConvertible
для преобразования в String
@propertyWrapper
struct StringRepresentation<T: LosslessStringConvertible> {
private var value: T?
var wrappedValue: T? {
get {
return value
}
set {
value = newValue
}
}
}
extension StringRepresentation: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if container.decodeNil() {
value = nil
} else {
let string = try container.decode(String.self)
value = T(string)
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
if let value = value {
try container.encode("\(value)")
} else {
try container.encodeNil()
}
}
}
. Это работает для
{
"value": "12.0"
}
и
{
"value": null
}
но происходит сбой при отсутствии свойства
{
}
с сообщением об ошибке
▿ DecodingError
▿ keyNotFound : 2 elements
- .0 : CodingKeys(stringValue: "value", intValue: nil)
▿ .1 : Context
- codingPath : 0 elements
- debugDescription : "No value associated with key CodingKeys(stringValue: \"value\", intValue: nil) (\"value\")."
- underlyingError : nil
Я предполагаю, что это происходит потому, что базовый StringRepresentation
не является опциональным. Как я могу сделать это необязательным?
Редактировать: Кроме того, я должен кодировать объект как
{
"value": null
}
, то есть значение не может быть опущено.