如何在CoreData中对相关对象进行排序?

时间:2018-11-29 20:51:58

标签: ios swift core-data

我在核心数据中与帖子和标签有很多联系。每个标签有很多帖子,每个帖子有很多标签。我有一个视图控制器,要在其中显示特定标签的所有与其相关的帖子。

我这样做:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        guard let appDelegate =
            UIApplication.shared.delegate as? AppDelegate else {
                return
        }
        let managedContext =
            appDelegate.persistentContainer.viewContext
        //2
        let fetchRequest: NSFetchRequest<Tag> = Tag.fetchRequest()
        //3
        fetchRequest.predicate = NSPredicate(format: "Tag.name == %@", tag.name!)
//        let sort = NSSortDescriptor(key: "timeStamp", ascending: true)
//        fetchRequest.sortDescriptors = [sort]

        fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedContext, sectionNameKeyPath: nil, cacheName: nil) as? NSFetchedResultsController<Tag>
        fetchedResultsController.delegate = self

        do {
            try fetchedResultsController.performFetch()
            tag = fetchedResultsController.object(at: IndexPath(item: 0, section: 0))
            tag = Tag(context: managedContext)
            let posts = tag.posts

我在底部的帖子对象是一组对象-无序。我想要一个按时间戳排序的帖子数组,这些帖子都属于这个特定标签,我不确定如何创建它。

我知道通常按照时间戳对项目进行排序,就像我在第3步中所做的那样,您会引入NSSortDescriptor(但已被注释掉)。但是我相信这会按照标记的时间戳对我的获取请求(标记)进行排序。每个标签都没有时间戳,我真正想要排序的是与该标签相关的帖子。所以我不认为这是做到这一点的方法。

我该如何处理?我想我可以使用swift,但感觉必须有一种Core Data方法可以按时间戳对相关对象进行排序

编辑:根据Paulw11的建议更新了方法:

 override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        guard let appDelegate =
            UIApplication.shared.delegate as? AppDelegate else {
                return
        }
        let managedContext =
            appDelegate.persistentContainer.viewContext
        //2
        let tagFetchRequest: NSFetchRequest<Tag> = Tag.fetchRequest()
        let postFetchRequest: NSFetchRequest<Post> = Post.fetchRequest()
        //3
        tagFetchRequest.predicate = NSPredicate(format: "%K == %@", #keyPath(Tag.name), tag.name!)

        do {
            let results = try managedContext.fetch(tagFetchRequest)
            tag = results.first
        } catch let error as NSError {
            print("Tag Fetch error: \(error) description: \(error.userInfo)")
        }

        guard let tag = tag else { return }

        postFetchRequest.predicate = NSPredicate(format: "%@ IN Post.tags", tag)
        let sort = NSSortDescriptor(key: "timeStamp", ascending: true)
        postFetchRequest.sortDescriptors = [sort]
        fetchedResultsController = NSFetchedResultsController(fetchRequest: postFetchRequest, managedObjectContext: managedContext, sectionNameKeyPath: nil, cacheName: nil)
        fetchedResultsController.delegate = self

        do {
            try fetchedResultsController.performFetch()
            posts = fetchedResultsController.fetchedObjects as! [Post]
            firstPostDate = posts.first?.timeStamp as Date?
            lastPostDate = posts.last?.timeStamp as Date?
            for (i,post) in posts.enumerated() {
                let date = post.timeStamp as Date?
                let day = date?.days(from: Calendar.current.startOfDay(for: firstPostDate!))
                indexMap[day!] = IndexPath(row: i, section: 0)
            }

这给出了此错误消息:

2018-11-29 15:36:56.261887-0800 SweatNetOffline[31250:17419187] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unimplemented SQL generation for predicate : (<Tag: 0x60000216b2a0> (entity: Tag; id: 0xc36a752f5b05e34c <x-coredata://F02C5E33-89B9-4814-9D1B-8C74CAEC7DA1/Tag/p79> ; data: {
    mostRecentThumbnail = nil;
    mostRecentUpdate = "2018-12-07 21:47:44 +0000";
    name = test;
    posts =     (
        "0xc36a752f5af9e34e <x-coredata://F02C5E33-89B9-4814-9D1B-8C74CAEC7DA1/Post/p48>"
    );
    uuid = nil;
}) IN Post.tags)'

看起来像将整个对象插入查询字符串。这似乎是错误的,但也许我需要以不同的方式设置对象的格式?

1 个答案:

答案 0 :(得分:0)

关键是要使用request.predicate = NSPredicate(format: "%@ IN self.tags", tag)

request.predicate = NSPredicate(format: "%@ IN Post.tags", tag)

相反

谓词的上下文是Post,所以我认为它不再需要访问。 Self.tags,tag和SELF.tags都可以工作。

相关问题