在 Swift 中,@Model 是 SwiftData 框架(从 Swift 5.9 和 iOS 17 开始引入)的一个新属性,用来标记数据模型类,使其成为持久化存储中的模型。这种属性的引入,使得定义数据模型变得更加简洁,方便了 SwiftUI 和数据持久化的整合。
@Model 主要用于 SwiftData,类似于 Core Data 中的实体模型,但语法更简洁现代,同时提供了与 SwiftUI 的无缝集成。它可以自动将模型的数据与持久化存储同步,让我们不再需要手动实现所有的存储代码。
@Model 的基本用法
使用 @Model 标记一个类,可以让 SwiftData 自动管理这个类的持久化状态。它自动将被标记的类视为数据模型,可以存储并管理其属性。
import SwiftData
@Model
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
在这个示例中,Person 类被 @Model 标记后,就会被 SwiftData 自动视为可持久化的数据模型。可以直接在 SwiftUI 中绑定并使用这个模型,轻松实现持久化功能。
特点和优势
自动化持久化:@Model 使得数据模型的持久化自动化,无需手动管理数据库或存储逻辑。
类型安全:与 Core Data 的动态类型系统不同,SwiftData 使用 Swift 原生的类型系统,使得模型更加类型安全。
轻松与 SwiftUI 集成:标记为 @Model 的类可以直接在 SwiftUI 中作为状态对象使用,简化数据绑定和视图更新。
声明式语法:相比 Core Data,@Model 使数据模型的声明更加简洁,并且避免了样板代码。
使用 @Attribute 进行属性配置
@Model 还可以与 @Attribute 配合使用,以提供额外的配置选项,例如,设置唯一约束或指定默认值。
import SwiftData
@Model
class Book {
var title: String
@Attribute(.unique) var isbn: String
var publicationYear: Int
var author: String?
init(title: String, isbn: String, publicationYear: Int, author: String? = nil) {
self.title = title
self.isbn = isbn
self.publicationYear = publicationYear
self.author = author
}
}
在这个例子中,isbn 属性被标记为唯一值,这样 SwiftData 会确保每本书的 ISBN 唯一。
结合 SwiftUI 使用 @Model
在 SwiftUI 中,您可以使用 @Model 标记的类来绑定数据。例如,可以将模型实例作为 @StateObject 或 @EnvironmentObject 直接绑定到视图中,并实现动态更新。
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query var books: [Book]
@State private var num = 0
var body: some View {
NavigationStack {
List(books) { book in
Text("书名: \(book.title), ISBN码: \(book.isbn), 出版年份: \(book.publicationYear), 作者: \(book.author ?? "佚名")")
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
// 添加新数据
let newBook = Book(title: "Some Book", isbn: "Some isbn", publicationYear: 2000, author: "Some Author \(num)")
num+=1
modelContext.insert(newBook)
}, label: {
Text("Add")
})
}
}
}
}
}
在这个例子中,@Query 提供了对数据库查询的声明式支持,使得我们可以直接在 SwiftUI 视图中获得模型数据的更新列表,而不需要手动管理数据库查询。
总结
@Model 是 SwiftData 框架中用于标记持久化模型的新属性,简化了数据模型的声明与使用。
与 @Attribute 等结合可以为属性添加配置项,例如唯一性约束。
@Model 可以直接与 SwiftUI 集成,使得数据绑定更加轻松,同时获得持久化功能。
注意。如果代码报错,可能为入口文件没有配置导致:
import SwiftUI
import SwiftData
@main
struct hackingwithswiftApp: App {
@State private var container: ModelContainer
init() {
do {
container = try ModelContainer(for: Book.self)
} catch {
fatalError("无法初始化 ModelContainer: \(error)")
}
}
var body: some Scene {
WindowGroup {
ContentView()
.modelContainer(container) // 将容器绑定到视图层次结构中
}
}
}
如果预览报错,则需要在预览中配置MOdelContainer。
#Preview {
// 创建一个 ModelContainer,并插入一些示例数据
let container = try! ModelContainer(for: Book.self)
let exampleBook = Book(title: "示例书籍", isbn: "1234567890", publicationYear: 2024, author: "作者名")
// 插入示例数据
let context = container.mainContext
context.insert(exampleBook)
try? context.save() // 注意错误处理,使用 try? 来避免崩溃
return ProfileView()
.modelContainer(container)
}