Я очень стараюсь передать объекты CoreData с сильными отношениями one2many по моему мнению Heirarchy.
Представьте себе приложение Todolist:
Каждый объект List имеет отношение one2many с объектом Task.
Каждый объект Task имеет отношение one2many с объектом SubTask.
Я запрашиваю CoreData в root с FetchedRequests для получения объекта List. Теперь я перебираю объекты Task и создаю View для каждого из них. Затем в каждом из этих представлений мне нужно перебирать его объекты подзадачи. На каждом из этих уровней можно вносить изменения и распространять их обратно.
Мне действительно тяжело с таким кодом:
struct TaskListView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@Binding var taskData: TaskData
var body: some View {
List{
ForEach(self.taskList.tasks ?? [], id: \.id) { t in
TaskRowView(taskData: $t)
}
}
}
}
Это дает много ошибок. Например:
Если я изменю его на использование индикаторов, он говорит, что не имеет атрибута .indicies
Прямо сейчас он говорит Generi c struct «ForEach» требует, чтобы «NSOrderedSet» соответствовал «RandomAccessCollection»
Значение типа «NSOrderedSet.Element» (иначе «Any») не имеет члена «id»
И много других на счет.
У вас есть лучший метод? Должен ли я делать запросы из coredata на каждом шагу? Я действительно не знаю, почему так сложно перенести то, что у меня уже было, с Bindings и структурой данных уровня root на coredata.
Кажется, я не могу запросить только один элемент из базы данных по UUID. Я sh это было больше похоже на mongodb, чем sql.
Вот пример проекта, который я сделал, чтобы упростить задачу. Интересно, может ли кто-нибудь взглянуть?
https://github.com/ryanpeach/MySwiftTaskList
Это основные виды:
TaskList + Extensions
extension TaskList: Identifiable {
var duration: Double {
var out = 0.0
for t in self.tasks ?? [] {
out += (t as! Task).duration
}
return out
}
func getTasks() -> [Task] {
var out: [Task] = []
for t in self.tasks ?? [] {
out.append(t as! Task)
}
return out
}
}
ContentView (root)
import SwiftUI
import CoreData
struct ContentView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(
entity: TaskList.entity(),
sortDescriptors: [
NSSortDescriptor(
keyPath: \TaskList.name,
ascending: true
)
]) var taskListList: FetchedResults<TaskList>
@State private var taskListName: String = ""
var body: some View {
NavigationView {
VStack {
HStack{
TextField("TaskList Name", text: $taskListName)
Button(action: {
self.addTaskList()
}){
Text("Create Task List")
}
}
List{
ForEach(self.taskListList, id: \.name) { tl in
NavigationLink(destination: TaskListView(taskList: tl)) {
Text(tl.name)
Text(String(tl.duration))
}
}
}
}
}
}
func addTaskList() {
let newTask = TaskList(context: managedObjectContext)
// newTask.id = UUID()
newTask.name = taskListName
do {
try managedObjectContext.save()
} catch {
print(error)
}
}
}
TaskListView
import SwiftUI
import CoreData
struct TaskListView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@State private var taskName: String = ""
/* Option1: Does not work
var fetchRequest: FetchRequest<Task>
var tasks: FetchedResults<Task>
@State private var _taskList: TaskList?
init(taskList: TaskList) {
fetchRequest = FetchRequest<Task>(
entity: Task.entity(),
sortDescriptors: [
NSSortDescriptor(
keyPath: \Task.order,
ascending: true
)
],
predicate: NSPredicate(format: "taskList = %@", taskList)
)
_taskList = taskList
tasks = fetchRequest.wrappedValue
}
*/
@Binding var taskList: TaskList
var body: some View {
VStack {
HStack{
TextField("Task Name", text: $taskName)
Button(action: {
self.addTask()
}){
Text("Create Task")
}
}
List{
ForEach(self.taskList.getTasks(), id: \.order) { <------- The errors happen here
t in
HStack{
Text(t.name)
Text(String(t.duration))
}
}
}
}
}
func addTask() {
let newTask = Task(context: managedObjectContext)
// newTask.id = UUID()
newTask.name = taskName
taskList.addToTasks(newTask)
do {
try managedObjectContext.save()
} catch {
print(error)
}
}
}
struct TaskListView_Previewer: View {
@State var taskList: TaskList
var body: some View {
TaskListView(
taskList: $taskList
)
}
}
Я очень ценю опыт обучения всему этому. Просто не совсем уверен, как я «должен» обрабатывать свои данные с помощью CoreData. У меня были примеры, работающие из статического c источника данных вроде json, и он работал безупречно, так что, я думаю, я просто не понимаю ограничений этого типа данных.