如何使用 NSFetchedResultsController 和多个获取的实体设置 collectionView(或 TableView)
How to setup a collectionView (or TableView) with NSFetchedResultsController and multiple fetched entities
我在这里读到,使用 1 个 NSFetchedResultsController 获取多个实体的方法是使用 parent child 继承模型。我有这样一个模型:
如您所见,TextPost、VideoPost 和 ImagePost 都具有作为 parent 实体的技能。我正在尝试制作一个 collectionView,所有三个 children 都会显示。我对如何设置委托方法有点困惑...
这是视图控制器的代码
class Timeline2ViewController: UIViewController {
@IBOutlet var postsCollectionView: UICollectionView!
var skillName: String?
fileprivate lazy var skillFetchedResultsController: NSFetchedResultsController<Skill> = {
let appDelegate =
UIApplication.shared.delegate as? AppDelegate
let managedContext =
appDelegate?.persistentContainer.viewContext
let request: NSFetchRequest<Skill> = NSFetchRequest(entityName: "Skill")
request.predicate = NSPredicate(format: "name == %@", self.skillName!)
let timeSort = NSSortDescriptor(key: "timeStamp", ascending: true)
request.sortDescriptors = [timeSort]
let skillFetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: managedContext!, sectionNameKeyPath: nil, cacheName: nil)
return skillFetchedResultsController
}()
override func viewDidLoad() {
super.viewDidLoad()
do {
try skillFetchedResultsController.performFetch()
} catch let error as NSError {
print("SkillFetchError")
}
}
}
extension Timeline2ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
guard let sectionInfo = skillFetchedResultsController.sections?[section] else { return 0 }
return sectionInfo.numberOfObjects
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = postsCollectionView.dequeueReusableCell(withReuseIdentifier: "pcell", for: indexPath) as? PostViewCell else { return fatalError("unexpected Index Path")
}
let post = skillFetchedResultsController[indexPath.row] /* This is the line im not sure about
cell.background
return cell
}
}
由于实际上只有 1 个实体 returned,我不确定如何访问特定索引路径中的元素。例如 skillFetchedResultsController[indexPath.row] 我认为只有 1 个实体 - 技能本身。我真的很想访问它的 children。我是否必须以某种方式子类化 skillFetchedResultsController 和 return 只有我感兴趣的 children?
编辑:@pbasdf 建议 - 我有这个模型:
现在当我像这样创建实体时:
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let textPost = NSEntityDescription.insertNewObject(forEntityName: "TextPost", into: managedContext) as! TextPost
textPost.text = "test text post"
try! managedContext.save()
然后我设置我的获取结果控制器来查看 "Post2",如下所示:
fileprivate lazy var skillFetchedResultsController: NSFetchedResultsController<Post2> = {
let appDelegate =
UIApplication.shared.delegate as? AppDelegate
let managedContext =
appDelegate?.persistentContainer.viewContext
let request: NSFetchRequest<Post2> = NSFetchRequest(entityName: "Post2")
// request.predicate = NSPredicate(format: "skill = %@", self.skill!)
let timeSort = NSSortDescriptor(key: "timeStamp", ascending: true)
request.sortDescriptors = [timeSort]
let skillFetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: managedContext!, sectionNameKeyPath: nil, cacheName: nil)
return skillFetchedResultsController
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
do {
try skillFetchedResultsController.performFetch()
} catch _ as NSError {
print("SkillFetchError")
}
}
我没有看到 returned 结果:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
guard let sectionInfo = skillFetchedResultsController.sections?[section] else { return 0 }
return sectionInfo.numberOfObjects
}
我是否需要 link 这两个?比如同时创建 Post object 和 TextPost object?当我尝试直接获取 TextPost objects 时,它起作用了。
我觉得问题出在你的模型上。您应该创建一个 Post
实体,并使其成为 TextPost
、VideoPost
和 ImagePost
的父实体。如果您的子实体有任何共同属性,请将它们从子实体移至 Post
实体。然后建立从Skill
到Post
.
的一对多关系
您的 FRC 应该获取 Post
个对象(默认情况下将包括所有子实体),必要时使用谓词将其限制为与您想要的 Skill
相关的那些 Post
个对象] 对象,例如
NSPredicate(format:"skill.name == %@",self.skillName!)
我在这里读到,使用 1 个 NSFetchedResultsController 获取多个实体的方法是使用 parent child 继承模型。我有这样一个模型:
如您所见,TextPost、VideoPost 和 ImagePost 都具有作为 parent 实体的技能。我正在尝试制作一个 collectionView,所有三个 children 都会显示。我对如何设置委托方法有点困惑...
这是视图控制器的代码
class Timeline2ViewController: UIViewController {
@IBOutlet var postsCollectionView: UICollectionView!
var skillName: String?
fileprivate lazy var skillFetchedResultsController: NSFetchedResultsController<Skill> = {
let appDelegate =
UIApplication.shared.delegate as? AppDelegate
let managedContext =
appDelegate?.persistentContainer.viewContext
let request: NSFetchRequest<Skill> = NSFetchRequest(entityName: "Skill")
request.predicate = NSPredicate(format: "name == %@", self.skillName!)
let timeSort = NSSortDescriptor(key: "timeStamp", ascending: true)
request.sortDescriptors = [timeSort]
let skillFetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: managedContext!, sectionNameKeyPath: nil, cacheName: nil)
return skillFetchedResultsController
}()
override func viewDidLoad() {
super.viewDidLoad()
do {
try skillFetchedResultsController.performFetch()
} catch let error as NSError {
print("SkillFetchError")
}
}
}
extension Timeline2ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
guard let sectionInfo = skillFetchedResultsController.sections?[section] else { return 0 }
return sectionInfo.numberOfObjects
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = postsCollectionView.dequeueReusableCell(withReuseIdentifier: "pcell", for: indexPath) as? PostViewCell else { return fatalError("unexpected Index Path")
}
let post = skillFetchedResultsController[indexPath.row] /* This is the line im not sure about
cell.background
return cell
}
}
由于实际上只有 1 个实体 returned,我不确定如何访问特定索引路径中的元素。例如 skillFetchedResultsController[indexPath.row] 我认为只有 1 个实体 - 技能本身。我真的很想访问它的 children。我是否必须以某种方式子类化 skillFetchedResultsController 和 return 只有我感兴趣的 children?
编辑:@pbasdf 建议 - 我有这个模型:
现在当我像这样创建实体时:
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let textPost = NSEntityDescription.insertNewObject(forEntityName: "TextPost", into: managedContext) as! TextPost
textPost.text = "test text post"
try! managedContext.save()
然后我设置我的获取结果控制器来查看 "Post2",如下所示:
fileprivate lazy var skillFetchedResultsController: NSFetchedResultsController<Post2> = {
let appDelegate =
UIApplication.shared.delegate as? AppDelegate
let managedContext =
appDelegate?.persistentContainer.viewContext
let request: NSFetchRequest<Post2> = NSFetchRequest(entityName: "Post2")
// request.predicate = NSPredicate(format: "skill = %@", self.skill!)
let timeSort = NSSortDescriptor(key: "timeStamp", ascending: true)
request.sortDescriptors = [timeSort]
let skillFetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: managedContext!, sectionNameKeyPath: nil, cacheName: nil)
return skillFetchedResultsController
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
do {
try skillFetchedResultsController.performFetch()
} catch _ as NSError {
print("SkillFetchError")
}
}
我没有看到 returned 结果:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
guard let sectionInfo = skillFetchedResultsController.sections?[section] else { return 0 }
return sectionInfo.numberOfObjects
}
我是否需要 link 这两个?比如同时创建 Post object 和 TextPost object?当我尝试直接获取 TextPost objects 时,它起作用了。
我觉得问题出在你的模型上。您应该创建一个 Post
实体,并使其成为 TextPost
、VideoPost
和 ImagePost
的父实体。如果您的子实体有任何共同属性,请将它们从子实体移至 Post
实体。然后建立从Skill
到Post
.
您的 FRC 应该获取 Post
个对象(默认情况下将包括所有子实体),必要时使用谓词将其限制为与您想要的 Skill
相关的那些 Post
个对象] 对象,例如
NSPredicate(format:"skill.name == %@",self.skillName!)