SwiftUI中 Swift Data 对象关联查询

SwiftData 中,你可以定义模型之间的关系,并且可以执行对象关联查询。这类似于 Core Data 中的关系模型。在下面的示例中,我们将新增一个 User 模型,并创建与 TodoItem 的关联关系。

1. 定义数据模型

新增一个 User 模型,并创建与 TodoItem 的一对多关系。

import SwiftData

@Model
class User {
    @Attribute(.primaryKey) var id: UUID
    var name: String
    var todos: [TodoItem] = []

    init(id: UUID = UUID(), name: String) {
        self.id = id
        self.name = name
    }
}

@Model
class TodoItem {
    @Attribute(.primaryKey) var id: UUID
    var title: String
    var isCompleted: Bool
    @Relationship var user: User? // Optional relationship to User

    init(id: UUID = UUID(), title: String, isCompleted: Bool = false, user: User? = nil) {
        self.id = id
        self.title = title
        self.isCompleted = isCompleted
        self.user = user
    }
}

2. 配置数据上下文

确保 User 模型也被添加到 modelContainer 中。

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .modelContainer(for: [User.self, TodoItem.self])
        }
    }
}

3. 使用关联查询

现在我们可以在 ContentView 中通过关联查询来获取特定用户的 TodoItem 列表。以下是如何使用 @Query 执行关联查询的示例:

import SwiftUI
import SwiftData

struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @State private var selectedUser: User?
    @State private var newItemTitle: String = ""
    
    var body: some View {
        NavigationView {
            VStack {
                // User selection (for demo purposes)
                if let users = try? modelContext.fetch(User.all()) {
                    Picker("Select User", selection: $selectedUser) {
                        ForEach(users, id: \.id) { user in
                            Text(user.name).tag(user as User?)
                        }
                    }
                    .pickerStyle(MenuPickerStyle())
                    .padding()
                }
                
                // Display todo items for the selected user
                if let user = selectedUser {
                    List {
                        ForEach(user.todos) { item in
                            HStack {
                                Text(item.title)
                                Spacer()
                                Button(action: {
                                    toggleCompletion(for: item)
                                }) {
                                    Image(systemName: item.isCompleted ? "checkmark.circle.fill" : "circle")
                                }
                                .buttonStyle(PlainButtonStyle())
                            }
                        }
                        .onDelete(perform: deleteItems)
                    }
                    
                    HStack {
                        TextField("New todo", text: $newItemTitle)
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                            .padding()
                        
                        Button(action: { addItem(for: user) }) {
                            Image(systemName: "plus")
                                .padding()
                        }
                    }
                }
            }
            .navigationTitle("Todo List")
        }
    }

    private func addItem(for user: User) {
        let newItem = TodoItem(title: newItemTitle, user: user)
        modelContext.insert(newItem)
        newItemTitle = ""
    }

    private func toggleCompletion(for item: TodoItem) {
        item.isCompleted.toggle()
    }

    private func deleteItems(at offsets: IndexSet) {
        if let user = selectedUser {
            for index in offsets {
                let item = user.todos[index]
                modelContext.delete(item)
            }
        }
    }
}

4. 解释代码

  • @Relationship: 在 TodoItem 模型中,使用 @Relationship 来表示与 User 的关系。user 是一个可选属性,表示任务可能没有分配给任何用户。
  • @Query: 你可以在 @Query 中使用过滤条件来获取与特定 User 相关的 TodoItem,或者在这种情况下,通过 user.todos 直接访问特定用户的任务列表。
  • 用户选择: 在示例中,我们提供了一个用户选择器(Picker),用于选择查看其待办事项的用户。

5. 总结

  • 关系模型: 通过 @Relationship 属性,可以轻松地定义模型之间的关系,并在 SwiftData 中管理这些关系。
  • 关联查询: 使用 @Query 或直接通过关系属性(如 user.todos)来执行关联查询,从而获取相关的对象数据。

这样,你可以在 SwiftUI 中有效地管理和查询关联数据。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值