NSSortDescriptor in Swift

Sort descriptors in a (SQLite-based) Core Data fetch request cannot use custom comparators and only a limited set of "built-in" comparison methods. This is documented in Fetch Predicates and Sort Descriptors in the "Core Data Programming Guide":

... The SQL store, on the other hand, compiles the predicate and sort descriptors to SQL and evaluates the result in the database itself. This is done primarily for performance, but it means that evaluation happens in a non-Cocoa environment, and so sort descriptors (or predicates) that rely on Cocoa cannot work. The supported sort selectors are compare: and caseInsensitiveCompare:, localizedCompare:, localizedCaseInsensitiveCompare:, and localizedStandardCompare: (the latter is Finder-like sorting, and what most people should use most of the time). In addition you cannot sort on transient properties using the SQLite store.

Fortunately, there is one that should fit your needs:

let sortDescriptor = NSSortDescriptor(key: "id", ascending: true,
                       selector: "localizedStandardCompare:")

localizedStandardCompare: does a "Finder-like" comparison and in particular treats digits within strings according to their numerical value.

For Swift 2.2/Xcode 7.3 and later:

let sortDescriptor = NSSortDescriptor(key: "id", ascending: true
                         selector: #selector(NSString.localizedStandardCompare))

for swift 4.2

You can sort array using NSSortDescriptor

let descriptor: NSSortDescriptor = NSSortDescriptor(key: "lastMessageDate", ascending: false)
let sortedResults = arrChatDialogs?.sortedArray(using: [descriptor])

The Swifty way:

var arr = ["A1", "A10", "A11", "A12", "A2", "A3"]
arr.sort {dropFirst($0).toInt() < dropFirst($1).toInt()}

So you could use that directly, or use it as the basis of the block for your comparator. If you insist on doing this in what is effectively Objective-C, you can use NSString compare:options: where the options: include NSNumericSearch.

Tags:

Ios

Swift