Swift 4 可解码 - 附加变量
Posted
技术标签:
【中文标题】Swift 4 可解码 - 附加变量【英文标题】:Swift 4 Decodable - Additional Variables 【发布时间】:2018-02-16 16:40:45 【问题描述】:目前我还没有想出或能够在网上找到的东西。
有没有办法将附加字段添加到包含 JSON 数据中不存在的可解码协议的结构上?
举个简单的例子,假设我有一个这样构造的 json 对象数组
“名称”:“名称1”, “网址”:“www.google.com/randomImage”
但是说我想添加一个 UIImage 变量到包含可解码的结构中,例如
struct Example1: Decodable
var name: String?
var url: String?
var urlImage: UIImage? //To add later
有没有办法实现可解码协议以便从 JSON 中获取名称和 url,但允许我稍后添加 UIImage?
【问题讨论】:
@Rob:我不这么认为——因为UIImage
不是Decodable
它甚至不会合成协议一致性
【参考方案1】:
要排除urlImage
,您必须手动符合Decodable
,而不是让其要求被综合:
struct Example1 : Decodable //(types should be capitalized)
var name: String?
var url: URL? //try the `URL` type! it's codable and much better than `String` for storing URLs
var urlImage: UIImage? //not decoded
private enum CodingKeys: String, CodingKey case name, url //this is usually synthesized, but we have to define it ourselves to exclude `urlImage`
在 Swift 4.1 之前,这仅在将 = nil
添加到 urlImage
时才有效,即使默认值 nil
通常假定为可选属性。
如果你想在初始化时为urlImage
提供一个值,而不是使用= nil
,你也可以手动定义初始化器:
init(from decoder: Decoder) throws
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
url = try container.decode(URL.self, forKey: .url)
urlImage = //whatever you want!
【讨论】:
编译器实际上可以为你合成init(from:)
。您只需要说var urlImage: UIImage? = nil
即可满足其对CodingKeys
中未列出的属性的默认值的需求(为什么它不接受nil
的隐式默认值我不太确定) .
非常感谢!这有点奇怪,我想这也是我的问题。我将 nil 值分配给从 json 属性中排除的变量并不断抛出错误。
需要明确分配nil
是我现在正在修复的行为中的一个错误(实际上是疏忽)。将来应该不需要这样做。
这个问题现在在 Swift 4.1 中得到修复,你可以省略 = nil
:)
在 Swift 5 中,这里需要 nil。此外,按照 cmets 中的建议将其设置为 nil 也不错,但是在解码后如何设置它而不自己实际编写 init(from:)?【参考方案2】:
实际上,我会让 urlImage 成为一个惰性变量。这样您就不必担心修改编码键。你所要做的就是写你的吸气剂,像这样......
struct Example1 : Decodable
var name : String?
var url : URL? // Better than String
lazy var urlImage: UIImage? =
// Put your image-loading code here using 'url'
()
【讨论】:
该解决方案的问题在于它仅适用于 var。如果我想做let example = ...
之类的事情,我将无法再访问 urlImage,因为示例对象现在是不可变的。
他的例子专门说'稍后添加'这就是我这样写的原因,但如果你希望它被视为'让',至少来自外界,只需使用@ 987654323@以上是关于Swift 4 可解码 - 附加变量的主要内容,如果未能解决你的问题,请参考以下文章