保存新内容时使用 FetchRequest 对 URL 进行排序会崩溃

Sorting URLs with FetchRequest crashes when new content is saved

我有一个应用程序,它使用核心数据和一个名为 Item 的实体,并具有属性“url”来保存 URL。 FetchRequest 看起来像下面的代码。

@FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.url, ascending: true)], animation: .default)

应用程序在创建项目时崩溃

    let newItem = Item(context: viewContext)
    newItem.url = URL(string: "https://www.google.com") //crashes after this line
    
    do {
        try viewContext.save()
    } catch {
        let nsError = error as NSError
        fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
    }

有了这个崩溃日志

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSURL compare:]: unrecognized selector sent to instance 0x2838187e0'

使用其他属性排序时(例如 String)不会导致应用程序崩溃。

我也尝试过从 init()

实现 fetchrequest
var fetchedItem: FetchRequest<Item>
init(){
    fetchedItem = FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.url, ascending: true)], animation: .default)
}

将排序从字符串更改为 url 有效,仅在创建要保存的新项目时崩溃。

这是一种错误的实施方式吗?还是不能同时使用 FetchRequest 和 Sort by URL?

尝试使用以下扩展名 URL(或 NSURL

extension URL {
    public func compare(_ other: URL) -> ComparisonResult {
        self.absoluteString.compare(other.absoluteString)
    }
}

请仔细查看错误信息

'-[NSURL compare:]: unrecognized selector sent

请同时查看 NSSortDescriptor documentation

You construct instances of NSSortDescriptor by specifying the key path of the property to be compared and the order of the sort (ascending or descending). Optionally, you can also specify a selector to use to perform the comparison, which allows you to specify other comparison selectors such as localizedStandardCompare: and localizedCaseInsensitiveCompare:. Sorting raises an exception if the objects to be sorted do not respond to the sort descriptor’s comparison selector

所以错误很明显:NSURL没有可比性。您需要一个像 descriptionabsoluteStringhostgoogle.com 部分)

这样的字符串

一个解决方案是像 Asperi 的回答那样创建 (NS)URL 的扩展。

一个更简单的解决方案是使用字符串键(路径)而不是 Swift 键路径创建 NSSortDescriptor

@FetchRequest(sortDescriptors: [NSSortDescriptor(key: "url.host", ascending: true)], animation: .default)