在 2023 年的全球开发者大会(WWDC)上,苹果公司推出了备受期待的新一代数据管理框架 —— SwiftData。作为 Core Data 的继任者,SwiftData 是否能在苹果生态系统中扮演关键角色?随着 2024 年的 WWDC 迫近,本文将评估 SwiftData 自首次发布以来,在 Xcode 15 期间(即首个大版本)的整体表现,并对其未来发展进行展望。
面向未来:SwiftData 一个现代的数据管理框架
SwiftData 并非完全从零开始构建,其核心技术仍然基于 Core Data。在 WWDC 2023 的首场关于 SwiftData 的 Session 中,苹果并未详细阐述这一点。
起初,我对苹果未在一开始就明确其与 Core Data 的联系感到困惑,甚至怀疑这是否是一种掩饰。然而,随着我对 SwiftData 的深入了解,我逐渐理解了苹果的策略。虽然 SwiftData 建立在 Core Data 久经考验的技术基础之上,其整体设计和呈现足以标志一个全新数据管理框架的诞生。苹果选择淡化其与 Core Data 之间的联系,目的是让开发者避免受到 Core Data 固有观念的影响,以便更好地理解 SwiftData 团队对现代数据管理框架的新解读。这一策略不仅强调了 SwiftData 作为独立框架的地位,还清晰地定义了其在苹果生态系统中的未来角色。
对于那些具有丰富 Core Data 经验的开发者来说,他们可能会发现,在理解和应用 SwiftData 提出的新编程哲学时会遇到一定的障碍,这与 UIKit 开发者转向 SwiftUI 时的挑战相似。
SwiftData 不仅简化了 Core Data 中一些复杂且鲜少使用的功能,而且引入了许多符合现代编程理念的实践。该框架充分利用了 Swift 语言的新特性,展示了如何构建安全、稳定且优雅的代码,为其在苹果生态中的核心角色奠定了基础。
因此,SwiftData 可以被视为一个全新且现代化的数据管理框架,具备在未来十年以上在苹果生态系统中发挥核心作用的潜力。
匆忙面世:SwiftData 面临的实际问题
SwiftData 的设计虽极具前瞻性,但推出显然过于仓促,首个版本不仅缺失一些重要功能,以下几个关键问题也严重影响了其表现和可用性:
-
不成熟的谓词转换能力:
SwiftData 引入了 Foundation 提供的新 Predicate 系统,它更安全且更符合人体工程学。虽然暂时不如传统的 NSPredicate 功能全面,但已足以满足大部分开发者的检索声明需求。然而,随着越来越多的应用开启数据云同步功能,模型中的属性越来越多地被声明为可选值,以满足同步要求。但当前 SwiftData 在转换包含可选值的谓词时( 将谓词转化为 SQL 指令 )表现不佳,尤其是几乎无法处理包含 “对多” 且可选的谓词。这种转换能力的不足不仅严重影响了 SwiftData 的可用性,也显著制约了使用 SwiftData 的应用所能提供的功能。
-
UI 响应数据更新异常:
SwiftData 利用 Swift 的现代并发模型提供了优雅的并发处理机制,允许开发者通过
@ModelActor
封装并发数据操作,从而有效避免了 Core Data 中常见的并发崩溃问题。然而,尽管经过一年多个小版本的更新,使用@ModelActor
进行的数据更新操作在多数情况下仍无法及时被 SwiftUI 视图响应。为了规避这一问题,开发者不得不放弃使用@ModelActor
或采用各种技巧来强迫视图更新,这不仅浪费了该特性的潜能,还严重影响了应用的效率。 -
模型验证与转换问题:
在 Core Data 中,启用数据网络同步功能时,Xcode 的模型编辑器会自动验证模型是否符合同步规范。相比之下,SwiftData 采用的是纯代码建模方式,这要求开发者必须手动编写代码进行模型验证。这种方法不仅增加了开发复杂度,还可能导致那些对同步规范理解不充分的开发者在项目接近完成时才发现模型不匹配,进而需要进行广泛的修改。此外,在将代码声明的模型转换为底层的 Core Data 可识别的
NSManagedObjectModel
过程中,特别是在缺少逆向关系标注的情况下(本可以省略的标注),也可能偶尔出现转换错误。这些错误通常难以发现,调试它们需要投入大量的时间和精力。 -
Codable 支持与数据存储不明确:
SwiftData 允许开发者将符合 Codable 协议的类型直接用作模型属性,极大提高了模型的清晰度并简化了操作。然而,官方尚未提供一个清晰的规范和明确的存储对应关系,这在实际使用中给开发者带来了不少挑战。首先,不是所有符合 Codable 协议的类型都能被稳定地转换,个别情况下可能造成程序崩溃。其次,缺乏官方的明确指导可能导致开发者在调整 Codable 类型时遇到模型升级的问题,特别是在使用数据云同步的场景中,新版本的模型可能无法进行无缝迁移(无法利用轻量级迁移)。
尽管 SwiftData 首个版本的功能不如 Core Data 全面,但如果该框架能够稳定运行且满足项目的需求,这些短板并不构成重大问题。然而,如前所述,存在的一些问题可能导致应用出现异常并在开发过程中带来不预期的障碍。
总体来看,由于 SwiftData 的推出显得仓促,其首个版本的实际表现并未完全达到预期,未能充分展示作为一个数据管理框架应有的能力和稳定性。因此,在即将到来的 WWDC 2024 上,对 SwiftData 进行必要的更新和增强变得尤为关键。
适用范围:SwiftData 的首个版本适合谁?
作为一个在 SwiftData 的研究上投入了不少精力的开发者,我对其精巧的设计和光明的前景充分认可,但必须承认,SwiftData 的首个版本并不适合所有开发者和项目。
-
对于初学者( 没有数据管理框架经验 ):不推荐
对数据管理框架不太熟悉的开发者可能会发现,由于对 SwiftData 的功能和限制认识不足,容易在项目开发过程中遇到难以逾越的障碍。
-
对于需求复杂的项目:不推荐
如果项目对数据管理框架的要求较高,Core Data 的成熟和功能完备性显然使其成为比 SwiftData 首版更合适的选择。尽管有能力在项目中融合使用 SwiftData 和 Core Data,但这样做投入的成本和精力可能得不偿失。
-
对于需求尚不明确的项目:不推荐
随着项目功能的不断增加,很可能在开发过程中发现 SwiftData 的首个版本无法满足开发需求。
-
对需求明确且不涉及 SwiftData 当前问题的项目:推荐
尽管首版存在限制,但对于功能需求简单、不涉及复杂关系和性能问题的项目,如果你能够规避 SwiftData 首个版本中的主要问题,那么 SwiftData 是可以胜任的。此外,如果项目不使用数据网络同步功能,SwiftData 的某些缺陷可以被进一步规避。
-
特定人群:可以尝试
对于那些充分了解项目功能需求并且完全掌握 SwiftData 首个版本的限制与不足的开发者,尤其是那些有较充分 Core Data 开发经验的人来说,使用 SwiftData 的首个版本进行正式项目开发尽管充满挑战,但也将带来解决困难的成就感。
尽管 SwiftData 首版的表现未能完全达到预期,其先进的设计理念和优雅的实现方式仍值得开发者借鉴。即便你当前不需要数据管理框架,或暂不考虑使用 SwiftData,学习和理解它仍然可以对你的未来开发工作带来积极影响。
在过去一年多的时间里,我撰写了十多篇 关于 SwiftData 的文章。这些文章详细探讨了 SwiftData 的原理和设计策略,对于希望深入理解这一框架的开发者来说,应该会非常有帮助。
展望未来:SwiftData 接下来的变化
随着 WWDC 2024 的临近,我期待在即将到来的更新中,SwiftData 首个版本中暴露的一些主要问题将得到解决。
正如前文所述,苹果正在将 SwiftData 打造成一个全新的数据管理框架,专门为当前及未来的苹果生态系统设计,特别是针对移动应用和配备高性能硬件(如高速 CPU 和固态硬盘)的环境。因此,许多在 Core Data 中具有特色的功能,鉴于市场和硬件环境的变化,可能不会被纳入 SwiftData。此外,SwiftData 也可能引入更精细的封装,以简化过去那些复杂的操作。
因此,我对苹果将以何种方式为 SwiftData 增加新功能感到好奇,而不仅仅是关注哪些功能将会被添加。
从 SwiftUI 的发展经验来看,SwiftData 成为苹果生态中关键的官方数据管理框架可能还需两到三年的时间。这一过程将是漫长且充满挑战的,但最终将为开发者提供强大的工具来构建未来的应用程序。
给当前已使用 SwiftData 的开发者的建议
如果你已经在项目中使用了 SwiftData,并且运行良好,那么首先恭喜你 🎉 !同时,我建议你更深入地了解 SwiftData 首个版本当前所面临的主要问题,并尽可能在之后的更新中规避这些问题。最后,在可能的情况下,建议在 iOS 18(或其他平台的新系统)发布后,提升项目的最低系统要求,以利用新系统可能带来的优化和改进。
附录:SwiftData 首个版本缺失的一些关键功能、主要问题及部分临时解决方案
- 惰性加载数据: SwiftData 不支持数据的惰性加载。
- 批量数据操作: 当前不支持数据批量操作,可结合 Core Data 实现。
- 多持久化存储支持: 在 iOS 17.4 前,SwiftData 不支持多持久化存储。
- 高级查询功能: 不支持
group
、having
、distinct
等高级查询功能,若有需求,可通过 SwiftDataKit 解决。 - 谓词功能限制: 启用同步功能后,对多关系的谓词表达能力受到限制。
- 公共数据库与数据共享: 不支持 同步公共数据库 与 共享数据。
- 性能问题: 对多关系中进行数据操作时可能引发 严重性能问题。
- 视图更新响应: 视图无法响应在
@ModelActor
中更新的数据。参考 解决方案一 与 解决方案二。 - 谓词合并: 不支持谓词合并。参考 解决方案。
- Codable 支持: 使用符合 Codable 协议的类型时,应确保该类型的所有属性与 SQLite 的基础属性一致(如整数、浮点数、日期等)。
- Codable 查询: Codable 类型的属性无法作为查询条件( Core Data 的 Composite Attributes 支持 )。
- 模型验证: 编写支持同步的数据模型时,应先进行 模型验证。
- 枚举存储: 不建议直接使用枚举作为存储类型,因为它们无法作为查询条件;最佳做法是保存其对应的 rawValue。
- 调用时机不足: SwiftData 尚不支持在如
didSave
、willSave
这类生命周期事件中添加自定义逻辑。这限制了在数据保存过程中执行特定操作的能力。可参考 解决方案 。 - 级联删除问题: SwiftData 在执行删除操作时,不会自动删除相关的关联数据( 删除规则为
cascade
)。可通过 SwiftDataKit 解决。 - 系统版本要求: 建议提高项目的最低系统版本要求,推荐最低为 iOS 17.2。