swift 3 - 创建具有关系的条目

swift 3 - create entry with relationship

我第一次处理核心数据中的关系。 我现在拥有的:

let appdelegate = NSApplication.shared().delegate as! AppDelegate
let context = appdelegate.persistentContainer.viewContext


// Create Person
let entityPerson = NSEntityDescription.entity(forEntityName: "Person", in: context)
let newPerson = NSManagedObject(entity: entityPerson!, insertInto: context)
newPerson.setValue("Max", forKey: "name")

// Create Book
let entityBooks = NSEntityDescription.entity(forEntityName: "Book", in: context)
let newBooks = NSManagedObject(entity: entityBooks!, insertInto: context)
newBooks.setValue("My Book", forKey: "title")

// Assign Book to Person
newPerson.setValue(NSSet(object: newBooks), forKey: "relationship")

这很好用。 它创建一个人和一本书,这将分配给创建的人。

但现在下一个问题: 我如何将新的书籍条目分配给核心数据中已有的人?

更新

这是我的核心数据

Person.swift

@objc(Person)
public class Person: NSManagedObject {

}

extension Person {

    @NSManaged public var name: String?
    @NSManaged public var books: Book?

}

Book.swift

@objc(Book)
public class Book: NSManagedObject {

}

extension Book {


    @NSManaged public var title: String?

}

我创建了 Person Max

 let appdelegate = NSApplication.shared().delegate as! AppDelegate
        let context = appdelegate.persistentContainer.viewContext

        // Create Person
        let entityPerson = NSEntityDescription.entity(forEntityName: "Person", in: context)
        let newPerson = NSManagedObject(entity: entityPerson!, insertInto: context)
        newPerson.setValue("Max", forKey: "name")

do {
            try context.save()
        } catch {}

核心数据结果:

然后我创建了一本名为 "My Book" 的书,应该分配给 Max

let appdelegate = NSApplication.shared().delegate as! AppDelegate
let context = appdelegate.persistentContainer.viewContext


        // Create Book
        let entityBook = NSEntityDescription.entity(forEntityName: "Book", in: context)
        let newBook = NSManagedObject(entity: entityBook!, insertInto: context)
        newBook.setValue("My Book2", forKey: "title")


        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Person")
        fetchRequest.predicate = NSPredicate(format: "name = %@", "Max")

        do {
            let result = try context.fetch(fetchRequest) as! [Person]

            if let person = result.first {
                person.setValue(NSSet(object: newBook), forKey: "books")
            }
        } catch { }


        do {
            try context.save()
        } catch {}

核心数据结果

完美!!

但现在我将创建第二本书 "My Book 2",它应该分配给 Max(上面的代码相同,但书名 "My Book 2"

核心数据结果

我希望你能理解这个问题:)

您必须执行提取以检查此人是否有空。

然后将此人分配给书(一对一关系),例如

let personName = "John"
let fetchRequest = NSFetchRequest<Person>(entityName: "Person")
let predicate = NSPredicate(format: "name == %@", personName)
fetchRequest.fetchLimit = 1
do {
    let persons = try context.fetch(fetchRequest)
    if let person = persons.first {
        newBook.person = person
    }
} catch {
   print(error)
}

代码利用了 Swift 3 种泛型类型。

编辑:

NSManagedObject 个子类的声明是错误的。

根据你的模型Person必须

extension Person {
    @NSManaged public var name: String?
    @NSManaged public var books: NSSet
}

Books必须是

extension Book {
    @NSManaged public var title: String?
    @NSManaged public var person: Person?
}

考虑至少使 nametitle 属性成为非可选属性。


PS:由于您使用的是 NSManagedObject 子类,因此您可以直接使用 属性 点符号而不是 KVC

newPerson.name = "Max"