JSONEncoderer dateEncodingStrategy não está funcionando
Eu estou tentando serializar uma estrutura para uma String usando o Swift 4's Encodable + JSONEncoder. O objeto pode conter valores heterogêneos como String, Matriz, Data, Int etc.
A abordagem usada funciona bem, com exceção de Date. JSONEncoderdateEncodingStrategy
propriedade não está tendo nenhum efeito.
Aqui está um trecho que reproduz o comportamento no Playground:
struct EncodableValue:Encodable {
var value: Encodable
init(_ value: Encodable) {
self.value = value
}
func encode(to encoder: Encoder) throws {
try value.encode(to: encoder)
}
}
struct Bar: Encodable, CustomStringConvertible {
let key: String?
let value: EncodableValue?
var description: String {
let encoder = JSONEncoder()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "E, d MMM yyyy"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
encoder.dateEncodingStrategy = .formatted(dateFormatter)
let jsonData = try? encoder.encode(self)
return String(data: jsonData!, encoding: .utf8)!
}
}
let bar1 = Bar(key: "bar1", value: EncodableValue("12345"))
let bar2 = Bar(key: "bar2", value: EncodableValue(12345))
let bar3 = Bar(key: "bar3", value: EncodableValue(Date()))
print(String(describing: bar1))
print(String(describing: bar2))
print(String(describing: bar3))
Resultado:
"{"key":"bar1","value":"12345"}\n"
"{"key":"bar2","value":12345}\n"
"{"key":"bar3","value":539682026.06086397}\n"
Para o objeto bar3: estou esperando algo como"{"key":"bar3","value":"Thurs, 3 Jan 1991"}\n"
, mas retorna a data no formato de estratégia .deferToDate padrão.
## EDIT 1 ##
Então, eu executei o mesmo código no XCode 9 e ele fornece a saída esperada, ou seja, formata corretamente a data em string. Estou pensando que 9.2 tem uma pequena atualização para o Swift 4, que está quebrando esse recurso. Não tenho certeza do que fazer a seguir.
## EDIT 2 ##
Como solução temporária, eu usei o seguinte trecho antes de mudar para a abordagem de @ Hamish usando um fechamento.
struct EncodableValue:Encodable {
var value: Encodable
init(_ value: Encodable) {
self.value = value
}
func encode(to encoder: Encoder) throws {
if let date = value as? Date {
var container = encoder.singleValueContainer()
try container.encode(date)
}
else {
try value.encode(to: encoder)
}
}
}