Sco*_*urn 4 core-data ios swift
我有一个小应用程序,我正在努力学习CoreData.这些是CoreData的实体.
extension Person {
@NSManaged var firstName: String?
@NSManaged var lastName: String?
@NSManaged var age: NSNumber?
@NSManaged var personToBook: NSSet?
}
extension Books {
@NSManaged var bookName: String?
@NSManaged var bookISBN: String?
@NSManaged var bookToPerson: Person?
}
Run Code Online (Sandbox Code Playgroud)
该应用程序是一个人的列表.属于列表中的每个人可以是一本书.
我很容易对人们进行排序.
let fetchRequest = NSFetchRequest(entityName: "Person")
let fetchSort = NSSortDescriptor(key: "lastName", ascending: true)
fetchRequest.sortDescriptors = [fetchSort]
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
do {
try fetchedResultsController.performFetch()
}
catch let error as NSError {
print("Unable to perform fetch: \(error.localizedDescription)")
}
Run Code Online (Sandbox Code Playgroud)
我正在努力解决的问题是如何按字母顺序对书籍进行排序,就像我是人一样.当我点击人员列表中的某个人时,我会查看UITableView包含书籍列表的人.在prepareForSegue中,我传入选定的人,上下文以及NSFetchedResultsController我在人员列表中使用的内容.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let vc = segue.destinationViewController as! BooksController
vc.person = fetchedResultsController.objectAtIndexPath(selectedIndex) as! Person
vc.context = self.context
vc.fetchedResultsController = self.fetchedResultsController
}
Run Code Online (Sandbox Code Playgroud)
该UITableView由person.personToBook填充.
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (person.personToBook?.count)!
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("BooksCell", forIndexPath: indexPath)
let book = person.personToBook?.allObjects[indexPath.row] as! Books
cell.textLabel?.text = book.bookName!
return cell
}
Run Code Online (Sandbox Code Playgroud)
以这种方式将书籍添加到正确的人:
let entity = NSEntityDescription.entityForName("Books", inManagedObjectContext: self.context)
let bookInstance = Books(entity:entity!, insertIntoManagedObjectContext: self.context)
bookInstance.bookName = alertController.textFields?[0].text
bookInstance.bookISBN = alertController.textFields?[1].text
self.person.mutableSetValueForKey("personToBook").addObject(bookInstance)
do {
try self.context.save()
self.tableView.reloadData()
}
catch let error as NSError {
print("Error saving a book \(error.localizedDescription)")
}
Run Code Online (Sandbox Code Playgroud)
personToBook是一个NSSet,并没有排序.我考虑过使用另一个NSFetchedResultsController to pull the list of books out, but there is nothing unique that is identifying the books as belonging to a specific user. For instance, I could have two people with the same name of John Doe. Because of this, I'd have no way to set theNSPredicate`,这样它只会为John Does中的一个提供书籍.
虽然我有一个,我可以添加某种UniqueID到Person实体,就像我在SQL中做的那样.这将确保我只能为正确的人获取图书记录.我被告知我不应该在CoreData中这样做.这让我相信必须有一些方法来对这个项目中的多个部分进行排序.
我可以对书籍数据进行排序的方式有哪些?
小智 12
NSSet是无序的.该集合不会按照您添加它们的顺序返回书籍.
以下是三种不同的方法,您可以使用这些方法按字母顺序排列书籍.
将模型更改为personToBook有序关系.这将使用NSOrderedSet而不是NSSet.按字母顺序将书籍添加到有序集合中.(注意这种方法的一个缺点是iCloud Core Data同步不支持有序关系.)
将NSSet书籍转换为数组并对该数组进行排序.
person.personToBook?.allObjects.sort({ $0.bookName < $1.bookName })
Run Code Online (Sandbox Code Playgroud)使用Book fetchedResultsController来获取和订购一个人的书籍.添加指定人员实体的谓词,以便仅返回该人员的书籍.由于您要与实体进行比较,而不是名称,因此如果有多个具有该名称的作者,则无关紧要.
let predicate = NSPredicate(format: "%K == %@", "bookToPerson", person)
Run Code Online (Sandbox Code Playgroud)另外,如果实体的属性或关系不是可选的,那么这些@NSManaged属性不需要是可选的.这将使您不必解开永远不会为零的值.您还可以指定集合中对象的类型,因此Swift知道它正在处理Book而不是AnyObject.
@NSManaged var personToBook: Set<Book> // Convention would be Book, not Books
Run Code Online (Sandbox Code Playgroud)
您还可以避免传递上下文或fetchedResultsController(人员).您已经传递了一个Person具有managedObjectContext属性的托管对象,并且您可以直接访问该人员的多人书籍关系以获取他们的书籍.Book视图控制器无需了解主视图控制器正在获取的任何其他人.
| 归档时间: |
|
| 查看次数: |
2059 次 |
| 最近记录: |