迅捷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 {}
获得核心数据:
然后我创建了一本标题为我的书"的书,该书应该分配给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?
}
请考虑至少使name
和title
属性为非可选.
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屋!