核心数据:使用PartialKeyPath而不是KeyPath进行排序



TL;DR

如何使用PartialKeyPath而不是KeyPath创建NSSortDescriptor

如何将PartialKeyPath转换为KeyPath

当我们在EntityPropertyQuery实现中声明SortingOptions时,我们将KeyPath传递给EntityQuerySortableByProperty初始值设定项。但我们在entities(matching:)函数的sortedBy参数中没有得到相同的KeyPath。相反,它给了我们一个PartialKeyPath,并且没有办法(afaik(使用这个PartialKeyPath来对核心数据进行排序,因为NSSortDescriptor需要KeyPathString,而不是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,但它不起作用,因为NSSortDescriptorinit需要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
}

最新更新