如何将 NSManagedObject 传递给 NSPredicate 以及如何保存一对多的实体

Posted

技术标签:

【中文标题】如何将 NSManagedObject 传递给 NSPredicate 以及如何保存一对多的实体【英文标题】:How to pass NSManagedObject to NSPredicate and how to save one-to-many Entities 【发布时间】:2015-05-13 04:14:01 【问题描述】:

我有一个简单的 ios8 Core Data 应用程序,它以 Master Detail 结构列出有关患者的信息。 Xcode 6.3.1 该应用程序的那部分工作正常 - 患者的表格视图,在第二个视图控制器中包含每个患者的详细信息。 Core Data 只有两个实体——Patient 和 Note,我设置了一对多的关系。每个 Patient 可以有多个 Notes,但每个 Note 只属于一个 Patient。

在患者详细信息页面上,我有一个按钮,用于启动属于该患者的备注列表和备注详细信息列表的第二个 tableview-viewcontroller 对。

使用 fetchedresults 控制器,数据会正确填充到患者表视图和患者详细信息视图中。但是,我似乎无法将注释与单个患者联系起来。我尝试检索属于单个患者的笔记也没有成功,但我怀疑这是因为我在保存笔记时没有将笔记链接到患者对象。

笔记保存代码:

func addNewNote() 

    makeEntryFieldsEnabledYES()

    //the Patient that owns this record is available as self.patientPassedIn
    //println("patientPassedIn is: \(patientPassedIn)")

    let context = kAppDelegate.managedObjectContext
    let entity = NSEntityDescription.entityForName("Note", inManagedObjectContext: kAppDelegate.managedObjectContext!)
    var noteToAdd = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: kAppDelegate.managedObjectContext!) as! Note

    noteToAdd.setValue(self.titleField.text, forKey: "title")
    noteToAdd.setValue(self.noteCategoryField.text, forKey: "noteCategory")
    noteToAdd.info = informationView.text
    noteToAdd.creationDate = NSDate()

    kAppDelegate.saveContext()

    performSegueWithIdentifier("unwindToNotesTableViewController", sender: self)

//addNewNote

我确实将相关的 Patient 对象传递给 Note 视图控制器,但我无法将注释链接到 那个对象。

如何为一对多实体构造保存操作,以便多个 Note 对象仅与单个实体相关 患者对象?那么如何构造获取请求以仅获取属于的 Note 对象 给定的病人?我想将 Patient 对象传递给谓词并检索适当的注释。

笔记获取代码:

var fetchedResultsController: NSFetchedResultsController 

    managedObjectContext = kAppDelegate.managedObjectContext

    if myFetchedResultsController != nil 
        return myFetchedResultsController!
    

    let fetchRequest = NSFetchRequest()

    // Check this: auto generate didn't work - fix that
    let entity = NSEntityDescription.entityForName("Note", inManagedObjectContext: managedObjectContext)

    fetchRequest.entity = entity
    fetchRequest.fetchBatchSize = 20

    let sortDescriptor = NSSortDescriptor(key: "creationDate", ascending: false)
    let sortDescriptors = [sortDescriptor]

    fetchRequest.sortDescriptors = [sortDescriptor]

    //prove that you have passed the Patient object
    var testString = passedInPatient?.lastName
    println(testString!)

    //try this for only retrieving the notes for the given patient
    //this does not work
    var notePredicate = NSPredicate(format: "passedInPatient")
    fetchRequest.predicate = notePredicate
    //
    //try above

    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

    var countError : NSError? = nil
    var count = managedObjectContext.countForFetchRequest(fetchRequest, error: &countError)
    println("The count is \(count)")

    aFetchedResultsController.delegate = self
    myFetchedResultsController = aFetchedResultsController

    var error: NSError? = nil
    if !myFetchedResultsController!.performFetch(&error) 
        //create an alert if the fetching fails
        println("Unresolved error \(error), \(error!.userInfo)")
        abort()
    //if !

    return myFetchedResultsController!

//var fetchedResultsController

我确实将相关的 Patient 对象传递给 Note 视图控制器,但我无法将便笺链接到该对象。

如何为一对多实体构造保存操作,以使多个 Note 对象仅与单个 Patient 对象相关?那么如何构造获取请求以仅获取属于给定 Patient 的 Note 对象?我想将 Patient 对象传递给谓词并检索适当的注释。

【问题讨论】:

[patient setNote: note]; 然后执行保存代码。这会将注释设置为保存到耐心的父对象。 【参考方案1】:

在您的addNewNote 函数中,添加另一行来设置关系(设置一对一关系最简单,CoreData 会自动为您设置反向关系):

noteToAdd.patient = patientPassedIn

在您的NSFetchedResultsController 中,您的谓词所需的格式如下:

var notePredicate = NSPredicate(format: "patient == %@", passedInPatient)
fetchRequest.predicate = notePredicate

【讨论】:

完美!对于其他有类似问题的人 - 确保 NSManaged 对象包含关系的属性。我在自动生成 Note.swift 类后创建了关系,所以我需要在该文件中添加“@NSManaged var patient : Patient”。

以上是关于如何将 NSManagedObject 传递给 NSPredicate 以及如何保存一对多的实体的主要内容,如果未能解决你的问题,请参考以下文章

将 NSManagedObject 传递给 UIViewController

将 NSManagedObject 传递给子上下文不起作用

restkit 0.20:无法将 NSManagedObject 传递给 getObject: 方法

NSManagedObject 传递给 ViewController 是不是反映所有更新

将对 NSManagedObject 的属性的引用传递给后台线程

通过@State 传递 NSManagedObject ...? SwiftUI