SwiftUI & Core Data - Как использовать родительскую запись в предикате? - PullRequest
1 голос
/ 31 октября 2019

Можно ли использовать базовую запись данных в предикате внутри оболочки свойств @FetchRequest в SwiftUI?

У меня есть список Project и список задач. Я хочу нажать на проект и перейти к списку связанных задач для этого проекта. Я не могу найти способ передать в родительский проект так, чтобы SwiftUI мог видеть до инициализации @FetcheRequest.

Я попытался поместить родительский проект в EnvironmentObject,Это вызывается, когда я перехожу из ProjectListView в TaskListView.

TaskListView()
   .environment(\.managedObjectContext, self.managedObjectContext)
   .environmentObject(self.projectToEdit)

Затем в TaskListView, который я добавил, пробовал это:

    @Environment(\.managedObjectContext) var managedObjectContext

    @EnvironmentObject var parentProject: Project

    @FetchRequest(
        entity: Task.entity(),
        sortDescriptors: [
            NSSortDescriptor(keyPath: \Task.name, ascending: true)
        ],
        predicate: NSPredicate(format: String(format: "%@%@", "taskProject", " == %@"), parentProject)
    ) var tasks: FetchedResults<Task>

Я получаю следующую ошибку в строке сПредикат.

Невозможно использовать элемент экземпляра parentProject в инициализаторе свойства;инициализаторы свойств запускаются до того, как станет доступным 'self'

Так есть ли способ написать предикат, который может использовать родительский проект? Передача проекта в представление задач не похоже на то, что он будет работать. Как еще мне использовать запись в предикате, подобном этому?

1 Ответ

1 голос
/ 10 ноября 2019

FetchRequest может быть создан динамически в методе init. Таким образом, вы можете варьировать предикаты и сортировать условия. Вот пример кода для достижения этого.

// sample Project class
class Project:NSManagedObject {
    var id : String
    var name : String
}

// sample Task class
class Task:NSManagedObject {
    var id : String
    var prjId : String
    var name : String
}

// Task List View
struct TaskListView: View {
    @Environment(\.managedObjectContext) var managedObjectContext

    private var tasksRequest: FetchRequest<Task>
    private var tasks: FetchedResults<Task> { tasksRequest.wrappedValue }

    private var project:Project

    // init Task with Project
    init(_ project:Project) {
        self.project = project

        // create FetchRequest
        self.tasksRequest = FetchRequest(
            entity: Task.entity(),
            sortDescriptors: [NSSortDescriptor(key: "name", ascending:true)],
            predicate: NSPredicate(format: "prjId == %@", project.id))
    }

    var body: some View {
        VStack {
            Section(header: Text("Tasks under \(project.name):")) {
                // access the fetched objects
                ForEach(tasks, id:\.id) { task in
                    Text("\(task.name)")
                }
            }
        }
    }
}

Тогда вызов TaskListView() будет выглядеть так:

// call to TaskListView
TaskListView(self.projectToEdit)
    .environment(\.managedObjectContext, self.managedObjectContext)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...