Apple 在 WWDC 23 发布了 SwiftData——更现代、更轻便的数据持久化框架。本质上是 Core Data 的现代 Swift 封装。背后依旧是 Core Data 引擎,但 API 全面 Swift 化、声明式,更贴合 SwiftUI。
由于其发布时间晚,且 Developer 更习惯使用 Core Data 或其他数据库框架作为 Apple 设备端的数据持久化框架,互联网上有关 SwiftData 的知识相对较少。因此,本篇文章用以记录 SwiftData 的使用。
欲构建 SwiftData 数据持久化框架,首先需构建项目 MVC 中的数据(Model):
新建一个 swift 文件
在你的项目中新建一个 swift 文件,并为其命名为你方便管理的文件名称(例如 Item、Entry 等)。随后,在你新建的文件中声明 SwiftData 和 Foundation 函数。SwiftData 的大体语法与常规的 Swift 接近,属于声明式语言,初步构建如下代码:
import SwiftData
import Foundation
@Model
class Entry {
var title: String
var createdAt: Date
// 存储富文本(RTF 格式)
var contentRTF: Data?
init(title: String, attributedContent: NSAttributedString? = nil, createdAt: Date = Date()) {
self.title = title
self.createdAt = createdAt
if let attributedContent = attributedContent {
self.contentRTF = try? attributedContent.data(
from: NSRange(location: 0, length: attributedContent.length),
documentAttributes: [.documentType: NSAttributedString.DocumentType.rtf]
)
}
}
var attributedContent: NSAttributedString? {
guard let contentRTF else { return nil }
return try? NSAttributedString(data: contentRTF,
options: [.documentType: NSAttributedString.DocumentType.rtf],
documentAttributes: nil)
}
}
Swift其中,@Model
是 SwiftData 的属性包装器,用来声明类为数据模型。被标记的类将由 Swift 自动处理数据持久化存储。
类中存在 3 个变量:title
,createdAt
,contentRTF
。它们分别存储标题、创建日期和被存储的富文本条目的内容。
init
:类的初始化(该函数用来初始化这个 SwiftData
类),其中存在必传参数 title
、可选参数 attributedContent
和 createdAt
。attributedContent
为富文本内容参数,默认值为 nil
,createdAt
为创建日期,默认值为当前时间(Date()
)。
init 函数
在数据持久化框架的初始化函数中,将传入的参数 title
,createdAt
,attributedContent
分别赋值给当前实例的属性。self.
表示当前实例。
其中,if let attributedContent = attributedContent {...}
在检查表示如果 attributedContent
有值则将传入参数赋值给同名常量,属于可选绑定。
self.contentRTF = try? attributedContent.data
尝试将富文本内容转换为 RTF 格式的二进制数据并赋值给 contentRTF
。try?
:尝试执行可能抛出错误的操作,如果失败则返回 nil
。
if let attributedContent = attributedContent {
self.contentRTF = try? attributedContent.data(
from: NSRange(location: 0, length: attributedContent.length),
documentAttributes: [.documentType: NSAttributedString.DocumentType.rtf]
)
}
Swiftfrom ...
确定富文本转换范围,从 0 开始,转换长度为富文本内容的总长度。随后,指定转换格式为 RTF 格式(.documentType
)。
var attributedContent: NSAttributedString? {
guard let contentRTF else { return nil }
return try? NSAttributedString(data: contentRTF,
options: [.documentType: NSAttributedString.DocumentType.rtf],
documentAttributes: nil)
}
Swift此函数以懒加载的形式被调用。它用于将富文本内容转换为 NSAttributedString
(Apple 的富文本处理类,用于存储带有样式信息的文本。)在实际的使用中,我们需要这个富文本处理类来提供编辑、显示等功能,而非存储于 SwiftData 中的二进制 RTF 格式。
函数首先检查 contentRTF
是否为空,为空则返回 nil
,否则尝试执行将 contentRTF
转换为 NSAttributedString
格式(从 RTF 创建富文本对象)。其中 try?
用于处理可能出现的错误,并返回 nil
。
以上为一个简单的 SwiftData 数据持久化框架的构建办法。实际开发时,我们可以在 Swift 的 MVC 结构中通过控制器(Controller)管理数据(Model),并将数据与用户交互(View)链接。