Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
909 views
in Technique[技术] by (71.8m points)

core data - Sorting URLs with FetchRequest crashes when new content is saved

I have an app which uses Core Data with an entity called Item and has the attribute "url" to save URL. The FetchRequest looks like the code below.

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

The app crashes when creating a item

    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)")
    }

with this crash log

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

When sorting using other attributes(ex. String) doesn't cause the app to crash.

I have also tried implementing fetchrequest from init()

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

Changing the sort from string to url works, only crashes when creating a new item to save.

Is this a wrong way for implementing? Or is it just not possible to use FetchRequest and Sort by URL together?

question from:https://stackoverflow.com/questions/66056599/sorting-urls-with-fetchrequest-crashes-when-new-content-is-saved

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Please look closely at the error message

'-[NSURL compare:]: unrecognized selector sent

and please look also at the 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

So the error is obvious: NSURL is not comparable. You need a string like description, absoluteString or just the host (the google.com part)


One solution is to create an extension of (NS)URL like in Asperi's answer.

An easier solution is to create the NSSortDescriptor with a string key (path) rather than a Swift key path.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...