Swift 4.0 Codable-解码子类,继承的类,异构数组
Swift 4.0引入了一个非常有用的API。 如果您一直在关注Swift项目和该版本中使用该语言的新功能,则可能已经听说过。 在使用某些REST API时,我遇到了一些问题,因此想在这里记录它们,以防其他人遇到相同的情况。
如果您熟悉Codable
,则可以跳过本节,如果不是,这就是文档页面上Apple汇总的方式:
使您的数据类型可编码和可解码,以与JSON等外部表示兼容。
关于如何使用此新API,已经有很多不错的文章。 这些是最好的,我建议阅读它们作为切入点:
编码和解码自定义类型
Swift 4 JSON解析终极指南
Swift 4 Decodable:超越基础📦
异构数组是指您拥有一个包含多个不同对象的JSON片段。 在我的情况下,这些对象是基类Drink
子类。每个子类具有不同的属性,需要序列化。
首先,需要定义模型,符合可Decodable
协议。 从基类开始,然后是子类。
这是基类,定义了与之关联的所有属性。 这没有什么复杂的,因此不需要编写自定义代码,它只使用标准API。
Beer
还具有alcohol_content
属性,因此我们需要添加它。 此类需要在基类之前进行初始化。 我们需要编写自己的自定义init方法。 您可以在第11行看到,我们将相同的解码器对象传递给超类,以便它可以对基类属性进行解码。
这就是我们将json转换为内存的方式。 这里没有什么复杂的,但是我们现在需要定义Drinks
对象。 该对象包含一个异构数组,因此我们需要自己实现Decodable
协议。
第2行显示我们将Drink
对象的数组作为属性添加到此类。
接下来,我们创建一个枚举DrinksKey
,该枚举用于解码包含饮料数组的字典。
我们还定义了一个枚举DrinkTypeKey
,它用于序列化数组中每个对象的类型字段。
最后的枚举DrinkTypes
与指定所有可能的饮料类型。
使用所有指定的枚举,我们可以进行序列化。
第19行:获取饮料字典- container
第20行:获取饮料数组— drinkArrayForType
第23行:复制drinksArray
数组— drinksArray
这是必需的,因为我们要迭代drinkArrayForType
。这样做时,我们将无法获取数组中每个元素的解码器对象。 请参阅下面的摘要。
第24行:迭代drinkArrayForType
容器
第25行:获取当前的饮料容器
第26行:解码type属性
现在,我们可以使用此解码属性来标识要解码的类。 但是,我们必须使用复制的drinksArray
对象进行解码,因为drinksArrayForType
的迭代器已移至下一个对象。 中提琴!
最后一步是我可以获得Decodable
API进行出价的唯一方法。 据我所知,没有办法从UnkeyedDecodingContainer
或KeyedDecodingContainer
获取解码器。这似乎是对API的限制,但我肯定有充分的理由使其无法使用。 仅在这种解码用例中公开这种依赖性似乎有些奇怪。
如果您有其他想法,请告诉我,可能值得进一步考虑,并为Swift API本身添加改进建议。 毕竟,这只是该API的第一次迭代,其可能的开发人员可能会错过此用例。
最初于 2017 年9月18日 发布在 medium.com 上。