【发布时间】:2019-10-17 10:49:09
【问题描述】:
在你回答之前:
我知道:
- 空字符串是无效的
URL - 我可以为
Employee编写一个自定义解码器 - 我可以将
url声明为String
我正在寻找一个更好的解决方案来解码可选的URL 本身。我希望我缺少一些 Codable 魔法!
所以,我有 JSON 之类的
let json = Data("""
{
"name": "Fred",
"url": ""
}
""".utf8)
以及包含可选 URL 的相应对象……
struct Employee: Decodable {
let name: String
let url: URL?
}
由于 JSON 中的 url 无效,我希望它解码为 nil,而不是抛出错误。
尝试以下不起作用(它不会被调用)......
extension Optional where Wrapped == URL {
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
do {
self = try container.decode(URL.self)
} catch {
self = nil
}
}
}
过去我用过……
struct FailableDecodable<T: Decodable>: Deodable {
let wrapped: T?
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
do {
self.wrapped = try container.decode(T.self)
} catch {
print("Error decoding failable object: \(error)")
self.wrapped = nil
}
}
}
struct Employee: Decodable {
let name: String
let url: FailableDecodable<URL>?
}
但这需要我不断参考url.wrapped。
有没有更好的解决方案?
【问题讨论】:
-
如果不是有效的 url,内置解码器会失败,您必须覆盖初始化解码器
-
多久调用一次 URL?如果只有一次,那么您可以考虑将模型中的类型设置为字符串,并在 JSON 序列化发生后将其转换为 URL?。
-
@Sh_Khan,我知道,谢谢。我想要一个不需要我为每个包含可选 URL 的对象编写自定义解码器的解决方案。因此,为什么我试图覆盖
Optional where Wrapped == URL,但没有成功,以及FailableDecodable(无论何时使用URL,都需要使用.wrapped)