在您回答之前:
我意识到:
URL Employeeurl为String我正在寻找一种更好的解决方案,用于解码可选项URL本身。我希望Codable我缺少一些魔法!
所以,我有JSON之类的
let json = Data("""
{
"name": "Fred",
"url": ""
}
""".utf8)
Run Code Online (Sandbox Code Playgroud)
以及包含可选URL的相应对象…
struct Employee: Decodable {
let name: String
let url: URL?
}
Run Code Online (Sandbox Code Playgroud)
由于urlJSON中的内容无效,因此我希望将其解码为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
}
}
}
Run Code Online (Sandbox Code Playgroud)
过去我用过……
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>?
}
Run Code Online (Sandbox Code Playgroud)
但这需要我不断提及url.wrapped。
有更好的解决方案吗?
如果您使用的是Swift 5.1,则可以使用@propertyWrapper:
let json = """
{
"name": "Fred",
"url": ""
}
""".data(using: .utf8)!
@propertyWrapper
struct FailableDecodable<Wrapped: Decodable>: Decodable {
var wrappedValue: Wrapped?
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
wrappedValue = try? container.decode(Wrapped.self)
}
}
struct Employee: Decodable {
let name: String
@FailableDecodable
private(set) var url: URL?
}
let employee = try! JSONDecoder().decode(Employee.self, from: json)
employee.url // nil
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
58 次 |
| 最近记录: |