swift 3 - create entry with relationship

耗尽温柔 提交于 2019-12-31 04:56:10

问题


i working the first time with relationships in core data. what i have now:

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

This works fine. It creates a person and a book, which will assign to the created person.

But now the next problem: How can I assign a new book entry to an person, which is already available in core data?

UPDATE

This is my Core Data

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?

}

I created the 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 {}

Result in Core Data:

Then i created a book with the title "My Book" which should assign to 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 {}

Core Data Result

PERFECT !!

But now i will create a second book "My Book 2" which should assign to Max (with the same code above but with book title "My Book 2"

The result of core data

I hope you unterstand the problem :)


回答1:


You have to perform a fetch to check if the person is available.

Then assign the person to the book (to-one relationship) for example

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

The code takes advantage of the Swift 3 generic types.

Edit:

The declaration of the NSManagedObject subclasses are wrong.

According to your model Person must be

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

and Books must be

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

Consider to make at least the name and title attributes non-optional.


PS: Since you are using NSManagedObject subclasses you can use the property directly with dot notation rather then KVC

newPerson.name = "Max"


来源:https://stackoverflow.com/questions/43846527/swift-3-create-entry-with-relationship

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!