SwiftData框架属性包装器@Model
SwiftData框架属性包装器@Model

SwiftData框架属性包装器@Model

在 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)
}

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注