Swift数据解析(第一篇) - 技术选型

这是Swift数据解析方案的系列文章:

Swift数据解析(第一篇) - 技术选型

Swift数据解析(第二篇) - Codable 上

Swift数据解析(第二篇) - Codable 下

Swift数据解析(第三篇) - Codable源码学习

Swift数据解析(第四篇) - SmartCodable 上

Swift数据解析(第四篇) - SmartCodable 下

数据解析一直是移动端的核心能力,跟我们的业务紧密相关。随着Swift的建设发展,Swift数据解析库的发展历程可以大致分为四个阶段:

  1. 从OC项目发展过来的Swift,沿用着OC的数据解析方案,比如YYModel。
  2. Swift4.0之前,官方并没有提供解析方案。一些三方库(HandyJSON,ObjectMapper)大放异彩。
  3. 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 等。

  1. 我们不得不给 Model 添加 @objc 标识,然后利用这些传统的 OC 库来进行转换。无法使用 Swift 中 struct 低内存占用、无内存泄露风险、线程安全、写时复制等众多特性。
  2. OC和Swift并不是完全互通的, 这就代表着有一定的差异性。并且OC已经完全停止更新了。Swift的一些新特性并不支持OC。
  3. 既然选择OC转Swift,这种常用能力就要考虑后续的迁移代价。混编OC,不是长久之计。
  4. 混编的编译代价。在OC代码中引用Swift代码时,通常情况下是通过导入 xxx-Swift.h 头文件来实现的,该头文件包含了整个Swift模块的公开接口和符号的声明,无法选择性地导入部分Swift代码。意味着改动一点Swift代码,就需要全量编译整个Swift模块的公开接口和符号的声明。

ObjectMapper

手动对每一个对象提供映射关系(映射属性与JSON键之间的关系),代码量较大。

HandyJSON

HandyJSON由于其便捷的使用,强大的异常兼容性,是Swift使用最广泛的数据解析库之一。

使用风险1: 官方建议不在使用

HandyJSON issue #447

HandyJSON issue #466

抱歉,现在已经不再建议继续使用。Swift发布4.0版本之前,官方未提供推荐的JSON处理方案,因此我们设计并实现了HandyJSON这套方案。但现在:1. Swift已经提供了Codable机制,可以相对便捷的进行JSON处理;2. HandyJSON的实现强依赖于Swift底层内存布局机制,这个机制是非公开、不被承诺、且实践证明一直在随着Swift版本变动的,HandyJSON需要跟进Swift的每次版本更新,更大的风险是,用户升级iOS版本可能会影响这个依赖,导致应用逻辑异常。

综上,我们不再建议继续使用。

使用风险2: 不稳定性

但是HandyJSON 是使用的反射机制实现的。反射机制的库Reflection已经被标记为废弃了。强依赖Swift底层内存布局机制(不被承诺,非公开的),HandyJSON需要跟进Swift的每次版本更新,更大的风险是,用户升级iOS版本可能会影响这个依赖,导致应用逻辑异常。

Reflection 源码说明

reflection-deprecated

根据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。

相关推荐
20岁30年经验的码农14 分钟前
若依微服务Openfeign接口调用超时问题
java·微服务·架构
百度Geek说16 分钟前
百度沈抖:全栈自主可控,为应用而生
架构
帅次1 小时前
Flutter Container 组件详解
android·flutter·ios·小程序·kotlin·iphone·xcode
Keya1 小时前
使用 tinypng 脚本打包为exe 进行压缩图片
前端·python·程序员
LLM大模型1 小时前
LangChain篇-自定义Callback组件
人工智能·程序员·llm
玩转AGI1 小时前
Deepseek篇--开源技术DualPipe 与 EPLB详解
人工智能·程序员·llm
头发够用的程序员2 小时前
小米玄戒O1架构深度解析(二):多核任务调度策略详解
android·linux·arm开发·智能手机·架构·手机
SoaringHeart3 小时前
SwiftUI组件封装:仿 Flutter 原生组件 Wrap实现
ios·swiftui
LLM大模型3 小时前
LangChain篇-多模态输入与自定义输出
人工智能·程序员·llm
LLM大模型3 小时前
LangChain篇-自定义工具调用
人工智能·程序员·llm