如何使用NSFetchedResultsController和多个获取的实体设置collectionView(或TableView)

问题描述 投票:1回答:1

我在这里阅读到,使用1个NSFetchedResultsController来获取多个实体的方法是使用父子继承模型。我有这样一个模型:

https://imgur.com/a/nckHzvr

您可以看到,TextPost,VideoPost和ImagePost都将Skill作为父实体。我正在尝试为所有三个孩子都出现的单个collectionView。我对如何设置委托方法有些困惑,但是...

这是视图控制器的代码

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

由于实际上仅返回了一个实体,所以我不确定如何在特定索引路径下访问元素。例如,我认为skillFetchedResultsController [indexPath.row]仅具有1个实体-技能本身。我真的很想接触它的孩子。我是否必须以某种方式子类skillFetchedResultsController并仅返回我感兴趣的子代?

编辑:带有@pbasdf建议-我有这个模型:

enter image description here

现在当我像这样创建实体时:

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

    }

我看不到以下结果:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    guard let sectionInfo = skillFetchedResultsController.sections?[section] else { return 0 }
    return sectionInfo.numberOfObjects
}

我是否需要将两者链接在一起?喜欢同时创建Post对象和TextPost对象吗?当我尝试直接获取TextPost对象时,它可以工作。

ios uitableview core-data uicollectionview nsfetchedresultscontroller
1个回答
1
投票

我认为问题出在您的模型中。您应该创建一个Post实体,并使其成为TextPostVideoPostImagePost的父实体。如果您的子实体有任何共同的属性,请将其从子实体移到Post实体。然后从SkillPost建立一对多关系。

您的FRC应该获取Post对象(默认情况下将包括所有子实体),并在必要时使用谓词将其限制为与所需Post对象相关的那些Skill对象,例如

NSPredicate(format:"skill.name == %@",self.skillName!)
© www.soinside.com 2019 - 2024. All rights reserved.