Установите NSSortDescriptor для CoreData, используя вычисляемое поле - PullRequest
0 голосов
/ 01 апреля 2020

Я использовал расширение для добавления вычисляемых свойств в базу данных CoreData. Я хотел бы использовать NSSortDescriptor с FetchRequest для фильтрации и сортировки информации CoreData на основе одного из этих вычисляемых свойств. Код без проблем компилируется и работает нормально при сортировке на основе собственного атрибута CoreData, но код падает во время выполнения при попытке применить NSSortDescriptor на основе вычисляемого поля.

Ниже приведен упрощенный фрагмент кода, взятого из моего файла "GameLog + CoreDataProperties.swift", где вычисленное свойство определено в расширении. Это компилируется и выполняется правильно:

import Foundation
import CoreData

extension GameLog {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<GameLog> {
        return NSFetchRequest<GameLog>(entityName: "GameLog")
    }

    @NSManaged public var date: Date?
    @NSManaged public var id: UUID?
    @NSManaged public var totalPoints: Int32
    @NSManaged public var numberOfGames: Int32

   /* Calculated fields for game statistics */
     @objc dynamic var scorePerGame: Double {
         return Double(totalPoints) / Double(numberOfGames) 
     }

   var wrappedDate: Date {
        date ?? Date()
    }
    var wrappedID: UUID {
        id ?? UUID()
    }
   var wrappedPoints: Int32 {
        totalPoints
    }
    var wrappedNumberOfGames: Int32 {
        numberOfGames
    }
}

Ниже приведен фрагмент кода, в котором я установил NSPredicate и NSSortDescriptor, которые будут использоваться для фильтрации и сортировки данных. Это также компилируется и работает правильно (после того, как я пометил вычисляемое свойство как "@ obj c dynamici c"):

// Set how the results will be filtered and sorted
predicate = NSPredicate(format: "date >= %@", Calendar.current.date(byAdding: .day, value: -7, to: Date())! as NSDate)

switch  self.chosenStats {
case 0:  // Total points
     sortDescriptor = NSSortDescriptor(keyPath: \GameLog.totalPoints, ascending: false)
case 1:  // Games
    sortDescriptor = NSSortDescriptor(keyPath: \GameLog.numberOfGames, ascending: false)
default:  // Points per game
    sortDescriptor = NSSortDescriptor(keyPath: \GameLog.scorePerGame, ascending: false)
}

Однако, когда приложение выполняется и фильтр сортировки применяется, он отлично работает в первых двух случаях (где сортировка основана на собственном атрибуте CoreData), но в третьем случае (с использованием NSSortDescriptor на основе вычисляемого свойства) происходит сбой приложения с ужасной ошибкой «Thread 1: signal SIGABRT».

Ниже приведен код, в котором я вызываю представление, используемое для фильтрации и сортировки:

FilteredGameView(filterCriteria: self.predicate, sortCriteria: [self.sortDescriptor])

Это код (упрощенный) для отображения отфильтрованных и отсортированных игр. Как отмечалось выше, это прекрасно работает при сортировке по собственным атрибутам CoreData (случай 0 и 1), но не по вычисляемому свойству (случай 2).

import SwiftUI

struct FilteredHOFView: View {

    var filteredGames: FetchRequest<GameLog>

    @Environment(\.managedObjectContext) var moc

    init(
        filterCriteria: NSPredicate,
        sortCriteria: [NSSortDescriptor]
    ) {
        self.filteredGames = FetchRequest(
            entity: GameLog.entity(),
            sortDescriptors: sortCriteria,
            predicate: filterCriteria
        )
    }


    var body: some View {
        List {
            ForEach(filteredGames.wrappedValue, id: \.self) { game in
                HStack {
                    Text("Show stats here")
                }
            }
        }
    }
}

Есть мысли о том, в чем проблема? Есть ли что-то особенное, что мне нужно сделать при применении маркера @ obj c?

1 Ответ

0 голосов
/ 02 апреля 2020

К сожалению, похоже, что это невозможно. Запрос на выборку Core Data не может сортировать по вычисляемому свойству, только по постоянным сохраненным свойствам. Я обнаружил следующий вопрос, который ранее пропустил на этом сайте.

Сортировка NSFetchedResultsController по вычисляемому свойству Swift в NSManagedObjectSubclass

Однако, если кто-то знает иначе, пожалуйста, дайте мне знаю.

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