如何在 CoreData 中对多个实体使用 Fetch Request?
How do I use a Fetch Request for multiple entities in CoreData?
目标:我想显示 Todo
项目的列表,我已经达到了截止日期。但我也想在 Todo 项目列表上方的同一视图中显示不同实体的列表 Categories
。类别是将您带到筛选到该类别的待办事项列表的按钮。我将类别关系设置为有很多待办事项。如何更改我的 FetchRequest 以支持添加的关系?
下面是当前的SectionedFetchRequest
。如果我尝试为类别添加新的 FetchRequest,我会崩溃。
@SectionedFetchRequest(entity: Todo.entity(),
sectionIdentifier: \.dueDateRelative,
sortDescriptors: [NSSortDescriptor(keyPath: \Todo.dueDate, ascending: true)],
predicate: nil,
animation: Animation.linear)
var sections: SectionedFetchResults<String, Todo>
ForEach(sections) { section in
Section(header: Text(section.id.description)) {
ForEach(section) { todo in
TodoRowView(todo: todo)
.frame(maxWidth: .infinity)
.listRowSeparator(.hidden)
}
.onDelete { indexSet in
deleteTodo(section: Array(section), offsets: indexSet)
}
}
}
// Causes Crash when added to existing Fetch Request
//@FetchRequest(entity: Category.entity(), sortDescriptors: []) var categories: FetchedResults<Category>
你可能想多了。如果您为类别添加 sectionIdentifier
,您可以相对容易地提供选项。
变量看起来像这样
extension Todo{
@objc
var categoryTitle: String{
self.relationship?.title ?? "no category"
}
}
然后在View
中添加几个变量
//Dictionary to store sort options
let sortOptions: [String: KeyPath<Todo, String>] = ["due date": \Todo.dueDateRelative, "category":\Todo.categoryTitle]
//Variable to use to filter list
@State var selectedSection: String = ""
//filter the `sections` by the selected section
//You can use nsPredicate too
var filteredSections: [SectionedFetchResults<String, Todo>.Element] {
sections.filter({ val in
if !selectedSection.isEmpty {
return val.id == selectedSection
}else{
return true
}
})
}
然后给用户一些按钮select
//Give the user sort options
Menu("sort"){
ForEach(Array(sortOptions.keys).sorted(by: <), id:\.self, content: { key in
Button(key, action: {
sections.sectionIdentifier = sortOptions[key]!
selectedSection = ""
})
})
}
//Give the user section options
Picker("sections", selection: $selectedSection, content: {
ForEach(sections, content: {section in
Text(section.id).tag(section.id)
})
Text("all").tag("")
}).pickerStyle(.segmented)
ForEach
会自动显示用户select离子
ForEach(filteredSections) { section in
目标:我想显示 Todo
项目的列表,我已经达到了截止日期。但我也想在 Todo 项目列表上方的同一视图中显示不同实体的列表 Categories
。类别是将您带到筛选到该类别的待办事项列表的按钮。我将类别关系设置为有很多待办事项。如何更改我的 FetchRequest 以支持添加的关系?
下面是当前的SectionedFetchRequest
。如果我尝试为类别添加新的 FetchRequest,我会崩溃。
@SectionedFetchRequest(entity: Todo.entity(),
sectionIdentifier: \.dueDateRelative,
sortDescriptors: [NSSortDescriptor(keyPath: \Todo.dueDate, ascending: true)],
predicate: nil,
animation: Animation.linear)
var sections: SectionedFetchResults<String, Todo>
ForEach(sections) { section in
Section(header: Text(section.id.description)) {
ForEach(section) { todo in
TodoRowView(todo: todo)
.frame(maxWidth: .infinity)
.listRowSeparator(.hidden)
}
.onDelete { indexSet in
deleteTodo(section: Array(section), offsets: indexSet)
}
}
}
// Causes Crash when added to existing Fetch Request
//@FetchRequest(entity: Category.entity(), sortDescriptors: []) var categories: FetchedResults<Category>
你可能想多了。如果您为类别添加 sectionIdentifier
,您可以相对容易地提供选项。
变量看起来像这样
extension Todo{
@objc
var categoryTitle: String{
self.relationship?.title ?? "no category"
}
}
然后在View
//Dictionary to store sort options
let sortOptions: [String: KeyPath<Todo, String>] = ["due date": \Todo.dueDateRelative, "category":\Todo.categoryTitle]
//Variable to use to filter list
@State var selectedSection: String = ""
//filter the `sections` by the selected section
//You can use nsPredicate too
var filteredSections: [SectionedFetchResults<String, Todo>.Element] {
sections.filter({ val in
if !selectedSection.isEmpty {
return val.id == selectedSection
}else{
return true
}
})
}
然后给用户一些按钮select
//Give the user sort options
Menu("sort"){
ForEach(Array(sortOptions.keys).sorted(by: <), id:\.self, content: { key in
Button(key, action: {
sections.sectionIdentifier = sortOptions[key]!
selectedSection = ""
})
})
}
//Give the user section options
Picker("sections", selection: $selectedSection, content: {
ForEach(sections, content: {section in
Text(section.id).tag(section.id)
})
Text("all").tag("")
}).pickerStyle(.segmented)
ForEach
会自动显示用户select离子
ForEach(filteredSections) { section in