TL;DR
如何使用PartialKeyPath
而不是KeyPath
创建NSSortDescriptor
?
或
如何将PartialKeyPath
转换为KeyPath
?
当我们在EntityPropertyQuery
实现中声明SortingOptions
时,我们将KeyPath
传递给EntityQuerySortableByProperty
初始值设定项。但我们在entities(matching:)
函数的sortedBy
参数中没有得到相同的KeyPath
。相反,它给了我们一个PartialKeyPath
,并且没有办法(afaik(使用这个PartialKeyPath
来对核心数据进行排序,因为NSSortDescriptor
需要KeyPath
或String
,而不是PartialKeyPath
。
详细信息
我正在使用AppIntents中的新查询属性在Shortcuts中过滤我的应用程序数据,但我无法将它提供的排序属性映射到Core data在谓词中期望的排序属性。
这是我的EntityPropertyQuery
实现:
extension ArtistQuery: EntityPropertyQuery {
static var sortingOptions = SortingOptions {
SortableBy(ArtistEntity.$name)
}
static var properties = QueryProperties {
Property(ArtistEntity.$name) {
EqualToComparator { NSPredicate(format: "name = %@", $0) }
ContainsComparator { NSPredicate(format: "name CONTAINS %@", $0) }
}
}
func entities(matching comparators: [NSPredicate],
mode: ComparatorMode,
sortedBy: [Sort<ArtistEntity>],
limit: Int?) async throws -> [ArtistEntity] {
Database.shared.findArtists(matching: comparators,
matchAll: mode == .and,
sorts: sortedBy.map { NSSortDescriptor(keyPath: $0.by, ascending: $0.order == .ascending) })
}
}
我的findArtists
方法实现如下:
static func findArtists(matching comparators: [NSPredicate],
matchAll: Bool,
sorts: [NSSortDescriptor]) -> [EArtist] {
...
}
正如我们在entities(matching:)
函数中看到的,我使用sortedBy
参数中的by
属性来创建NSSortDescriptor
,但它不起作用,因为NSSortDescriptor
init需要KeyPath
,而不是PartialKeyPath
:
Cannot convert value of type 'PartialKeyPath<ArtistEntity>' to expected argument type 'KeyPath<Root, Value>'
那么,我可以使用PartialKeyPath
而不是KeyPath
创建NSSortDescriptor
吗?或者可能将PartialKeyPath
转换为KeyPath
?
多亏了这个Gist,我找到了一个解决方案。无法直接从EntityQuerySort转换为NSSortDescriptor。相反,我们必须手动转换:
private func toSortDescriptor(_ sortedBy: [Sort<ArtistEntity>]) -> [NSSortDescriptor] {
var sortDescriptors = [NSSortDescriptor]()
if let sort = sortedBy.first {
switch sort.by {
case .$name:
sortDescriptors.append(NSSortDescriptor(keyPath: EArtist.name, ascending: sort.order == .ascending))
default:
break
}
}
return sortDescriptors
}