Как отсортировать связанные объекты в CoreData? - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть много-много отношений в Базовых Данных с постами и тегами.Каждый тег имеет много постов, и каждый пост имеет много тегов.У меня есть контроллер представления, в котором я хочу отобразить для определенного тега все сообщения, связанные с ним.

Я делаю это:

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

Объект моих постов внизу - это набор объектов - неупорядоченный.Я хочу, чтобы массив записей, упорядоченных по отметке времени, принадлежал именно этому тегу, и я не уверен, как его создать.

Обычно я знаю, что для сортировки элементов по отметке времени вы вводите NSSortDescriptor, как я это делал на шаге 3 (но закомментирован).Но я верю, что это отсортировало бы мой запрос на выборку (Tag) по метке времени Tag.У каждого тега нет метки времени, и я действительно хочу отсортировать записи, связанные с этим тегом.Поэтому я не верю, что это способ сделать это.

Как мне поступить?Я думаю, что я мог бы просто использовать 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 голосов
/ 10 декабря 2018

Ключ должен был использовать request.predicate = NSPredicate(format: "%@ IN self.tags", tag)

вместо request.predicate = NSPredicate(format: "%@ IN Post.tags", tag)

Контекст предиката - это сообщение, поэтому к нему больше не нужно обращаться, я полагаю, этопредполагается.Self.tags, теги и SELF.tags все работают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...