这是Swift数据解析方案的系列文章:
Swift数据解析(第四篇) - SmartCodable 上
Swift数据解析(第四篇) - SmartCodable 下
数据解析一直是移动端的核心能力,跟我们的业务紧密相关。随着Swift的建设发展,Swift数据解析库的发展历程可以大致分为四个阶段:
- 从OC项目发展过来的Swift,沿用着OC的数据解析方案,比如YYModel。
- Swift4.0之前,官方并没有提供解析方案。一些三方库(HandyJSON,ObjectMapper)大放异彩。
- Swift4.0之后,官方推出Codable协议的数据解析方案。
- Swift 4.0: 在Swift 4.0中,苹果引入了Codable协议。Codable协议是Encodable和Decodable协议的组合,它使得对象的编码和解码变得非常简单。通过遵循Codable协议,开发者可以使用Swift的内置JSONEncoder和JSONDecoder来自动进行对象与JSON之间的转换。
- Swift 4.1: 在Swift 4.1中,苹果对Codable进行了一些改进和优化。它增加了对keyed container的支持,使得处理复杂的嵌套数据结构更加方便。
- Swift 5.0: 在Swift 5.0中,苹果对Codable进行了一些性能优化,提高了编码和解码的效率。此外,它还引入了新的编码和解码策略,使开发者能够更好地控制数据。
- Swift 5.1: 在Swift 5.1中,苹果提供了 @propertyWrapper,为数据解析提供了更好的灵活性。
混编OC方案
从OC项目发展过来的Swift,沿用着OC的数据解析方案,比如 JSONModel、MJExtension、YYModel 等。
- 我们不得不给 Model 添加 @objc 标识,然后利用这些传统的 OC 库来进行转换。无法使用 Swift 中 struct 低内存占用、无内存泄露风险、线程安全、写时复制等众多特性。
- OC和Swift并不是完全互通的, 这就代表着有一定的差异性。并且OC已经完全停止更新了。Swift的一些新特性并不支持OC。
- 既然选择OC转Swift,这种常用能力就要考虑后续的迁移代价。混编OC,不是长久之计。
- 混编的编译代价。在OC代码中引用Swift代码时,通常情况下是通过导入 xxx-Swift.h 头文件来实现的,该头文件包含了整个Swift模块的公开接口和符号的声明,无法选择性地导入部分Swift代码。意味着改动一点Swift代码,就需要全量编译整个Swift模块的公开接口和符号的声明。
ObjectMapper
手动对每一个对象提供映射关系(映射属性与JSON键之间的关系),代码量较大。
HandyJSON
HandyJSON由于其便捷的使用,强大的异常兼容性,是Swift使用最广泛的数据解析库之一。
使用风险1: 官方建议不在使用
抱歉,现在已经不再建议继续使用。Swift发布4.0版本之前,官方未提供推荐的JSON处理方案,因此我们设计并实现了HandyJSON这套方案。但现在:1. Swift已经提供了Codable机制,可以相对便捷的进行JSON处理;2. HandyJSON的实现强依赖于Swift底层内存布局机制,这个机制是非公开、不被承诺、且实践证明一直在随着Swift版本变动的,HandyJSON需要跟进Swift的每次版本更新,更大的风险是,用户升级iOS版本可能会影响这个依赖,导致应用逻辑异常。
综上,我们不再建议继续使用。
使用风险2: 不稳定性
但是HandyJSON 是使用的反射机制实现的。反射机制的库Reflection已经被标记为废弃了。强依赖Swift底层内存布局机制(不被承诺,非公开的),HandyJSON需要跟进Swift的每次版本更新,更大的风险是,用户升级iOS版本可能会影响这个依赖,导致应用逻辑异常。
根据Swift官方文档,自Swift 5.1起,Reflection(反射)已被标记为废弃。这意味着在最新的Swift版本中,不再建议使用Reflection来进行对象的反射操作。
然而,Mirror(镜像)仍然可以使用,并且是Swift标准库的一部分。虽然Reflection被废弃,但Mirror仍然提供了一种访问和操作对象的结构化方式。因此,您仍然可以使用Mirror来获取对象的类型信息、属性和值等。
请注意,由于Reflection已被废弃,未来的Swift版本可能会进一步减少或移除对Mirror的支持。因此,在使用Mirror时,建议密切关注Swift的更新和变化,以确保您的代码与最新的Swift版本兼容。
Codable的三方库
调研了Star前几名的Codable三方库,都有不如意的地方。
三方库 | Star | 优点 | 缺点 |
---|---|---|---|
BetterCodable | 1.6K | 可以兼容类型不一致的情况,使用属性包装器实现,使用较为方便。 | 没法兼容缺失字段的情况。数据少了字段,就会整段解析失败。 |
Codextended | 1.5K | 对Codable协议的扩展增强,极大的简化了使用codable的代码量。 | 并没有改变每个Model都需要异常处理的情况。 |
AnyCodable | 1.2K | 对数据层处理,兼容了字典和Json之间的无障碍转化 | 并没有形成完整的数据解析框架。 |
SmartCodable
我们决定自己尝试写一套基于Codable的Swift数据解析框架,并遵循 安全 ,方便使用 ,低学习成本的原则。
我们写了很多demo,详细学习了Codable相关的API。 设计了很多场景,收集Codable的表现。 研读源码,了解实现本质。
做完这些之后,开发了SmartCodable。