我正在尝试使用 Swift 4 的 Encodable+JSONEncoder 将结构序列化为字符串。该对象可以保存异构值,如 String、Array、Date、Int 等。
除日期外,使用的方法工作正常。JSONEncoder 的dateEncodingStrategy
属性没有任何作用。
这是重现 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))
输出:
"{"key":"bar1","value":"12345"}\n"
"{"key":"bar2","value":12345}\n"
"{"key":"bar3","value":539682026.06086397}\n"
对于 bar3 对象:我期待类似的东西"{"key":"bar3","value":"Thurs, 3 Jan 1991"}\n"
,但它以默认的 .deferToDate 策略格式返回日期。
##编辑1##
所以我在 XCode 9 中运行了相同的代码,它给出了预期的输出,即正确地将日期格式化为字符串。我认为 9.2 对 Swift 4 进行了小幅升级,这打破了这个特性。不知道下一步该怎么做。
##编辑2##
作为临时补救措施,在使用闭包更改为@Hamish 的方法之前,我使用了以下代码段。
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)
}
}
}