簡體   English   中英

核心數據:使用 PartialKeyPath 而不是 KeyPath 進行排序

[英]Core Data: sort using a PartialKeyPath instead of a KeyPath

TL;博士

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

或者

如何將PartialKeyPath轉換為KeyPath

當我們在EntityPropertyQuery實現中聲明SortingOptions時,我們將KeyPath傳遞給EntityQuerySortableByProperty初始化程序。 但是我們在entities(matching:)函數的sortedBy參數中沒有得到相同的KeyPath 相反,它給了我們一個PartialKeyPath ,並且沒有辦法(afaik)使用這個PartialKeyPath在 Core Data 中排序,因為NSSortDescriptor需要KeyPathString ,而不是PartialKeyPath

細節

我正在使用 AppIntents 中的新查詢屬性在快捷方式中過濾我的應用程序數據,但我無法 map 排序屬性,它為我提供了 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:) function 中看到的那樣,我使用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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM