按翻译后的属性对 Core-Data 对象进行排序

Sort Core-Data objects by translated properties

我的应用程序最近进行了本地化,现在我遇到了 NSSortDescriptor 和 Core Data 的问题。

基本上,我有一个对具有预定义英语属性的对象使用 NSSortDescriptor 的提取请求,现在我需要使用翻译后的版本进行排序。

当使用基本语言(英语)时,这有效:

func initTodayGrouped(delegate: NSFetchedResultsControllerDelegate) -> NSFetchedResultsController<Category> {
    let request: NSFetchRequest<Category> = Category.fetchRequest()
    request.predicate = NSPredicate(format: "active == %d", true)
    let sort = NSSortDescriptor(key: #keyPath(Category.title), ascending: true, selector: #selector(NSString.localizedCompare(_:)))
    let sectionSort = NSSortDescriptor(key: #keyPath(Category.typeSection), ascending: true, selector: #selector(NSString.localizedCompare(_:)))
    request.sortDescriptors = [sectionSort, sort]
    let controller = NSFetchedResultsController(fetchRequest: request,
                                                managedObjectContext: managedContext,
                                                sectionNameKeyPath: #keyPath(Category.typeSection),
                                                cacheName: nil)
    controller.delegate = delegate
    return controller
}

Category是我的核心数据实体,Category.typeSection是一个字符串,是用来排序sections的属性。

extension Category {

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

    @NSManaged public var active: Bool
    @NSManaged public var color: String?
    @NSManaged public var icon: String?
    @NSManaged public var id: UUID?
    @NSManaged public var index: Int16
    @NSManaged public var subtitle: String?
    @NSManaged public var title: String?
    @NSManaged public var typeSection: String? // <-- HERE
    @NSManaged public var events: NSSet?

}

现在我需要使用这个 属性 的本地化版本。

我考虑过使用 replace/override NSString.localizedCompare(_:) 使用 NSLocalizedString 而不是字符串本身的方法进行 NSString 扩展,但我想我无法将它暴露给Objective-C 运行时(我得到“不支持的排序描述符”)。然后我想也许在实体扩展中添加一个计算的 属性,这将 return NSLocalizedString,例如 Category.translatedTypeSection 但我得到“由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序”,原因: 'keypath translatedTypeSection not found in entity Category'").

最后,我认为 会起作用,因为 OP 有一个非常相似的问题,但我无法将其转换为 Swift。


TL;DR

我的核心数据实体有一个typeSection属性,这是一个预定义(非用户输入)英文字符串,用于排序部分。

既然该应用程序已本地化为其他语言,我需要根据此 属性 的翻译版本而不是数据库中记录的基本语言版本进行排序。

这与将您的代码公开给 ObjC 或翻译代码无关。您遇到麻烦是因为当您将 Core Data 与 SQLite 一起使用时,排序描述符在 SQLite 中执行。 ObjC 和 Swift 代码都不能用于排序,只能转换为 SQLite 排序规则的表达式。这就是“不受支持的排序描述符”的意思,它是框架告诉你它不能将该描述符转换成在 SQLite.

中运行的东西

找不到键路径错误的发生是因为,虽然排序描述符对于 SQLite 是可接受的,但它只适用于持久存储中存在的键。 SQLite 中不存在计算属性,所以发生错误是因为,在 SQL 术语中,您试图按那里不存在的列进行排序。

您 link 的答案与您的代码有重大差异。您正在尝试使用排序描述符作为提取的一部分,这需要一个可以在 SQLite 中工作的排序描述符。 linked 答案执行提取时根本没有排序描述符。然后它在内存中对结果进行排序。您也可以这样做,并且您尝试过的任何一种方法都应该有效,因为这两种方法都适用于对内存中的数组进行排序。