SwiftUI和核心数据-如何在谓词中使用父记录?

时间:2019-10-31 12:47:30

标签: core-data swiftui

是否可以在SwiftUI的@FetchRequest属性包装器中的谓词中使用核心数据记录?

我有一个项目列表和一个任务列表。我想点击一个项目并导航到该项目的相关任务列表。我似乎找不到一种方法来传递父项目,而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”;属性初始化程序在“自我”可用之前运行

那么有没有一种方法可以使用父项目来编写谓词?将项目传递到任务视图似乎无法正常工作。在这样的谓词中我还要如何使用记录?

1 个答案:

答案 0 :(得分:2)

可以在init方法中动态创建FetchRequest。这样,您可以更改谓词和排序条件。这是一些实现此目的的示例代码。

// 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)