迅捷3-创建具有关系的条目 [英] swift 3 - create entry with relationship

查看:74
本文介绍了迅捷3-创建具有关系的条目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

获得核心数据:

然后我创建了一本标题为我的书"的书,该书应该分配给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"

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

解决方案

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"

这篇关于迅捷3-创建具有关系的条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆