Until now (Swift 2.2) I have been happily using the code from this answer - it's swifty, it's elegant, it worked like a dream.
extension MutableCollectionType where Index : RandomAccessIndexType, Generator.Element : AnyObject {
/// Sort `self` in-place using criteria stored in a NSSortDescriptors array
public mutating func sortInPlace(sortDescriptors theSortDescs: [NSSortDescriptor]) {
sortInPlace {
for sortDesc in theSortDescs {
switch sortDesc.compareObject($0, toObject: $1) {
case .OrderedAscending: return true
case .OrderedDescending: return false
case .OrderedSame: continue
}
}
return false
}
}
}
extension SequenceType where Generator.Element : AnyObject {
/// Return an `Array` containing the sorted elements of `source`
/// using criteria stored in a NSSortDescriptors array.
@warn_unused_result
public func sort(sortDescriptors theSortDescs: [NSSortDescriptor]) -> [Self.Generator.Element] {
return sort {
for sortDesc in theSortDescs {
switch sortDesc.compareObject($0, toObject: $1) {
case .OrderedAscending: return true
case .OrderedDescending: return false
case .OrderedSame: continue
}
}
return false
}
}
}
Swift 3 changes everything.
Using the code migration tool and Proposal SE- 0006 - sort() => sorted(), sortInPlace() => sort() - I have gotten as far as
extension MutableCollection where Index : Strideable, Iterator.Element : AnyObject {
/// Sort `self` in-place using criteria stored in a NSSortDescriptors array
public mutating func sort(sortDescriptors theSortDescs: [SortDescriptor]) {
sort {
for sortDesc in theSortDescs {
switch sortDesc.compare($0, to: $1) {
case .orderedAscending: return true
case .orderedDescending: return false
case .orderedSame: continue
}
}
return false
}
}
}
extension Sequence where Iterator.Element : AnyObject {
/// Return an `Array` containing the sorted elements of `source`
/// using criteria stored in a NSSortDescriptors array.
public func sorted(sortDescriptors theSortDescs: [SortDescriptor]) -> [Self.Iterator.Element] {
return sorted {
for sortDesc in theSortDescs {
switch sortDesc.compare($0, to: $1) {
case .orderedAscending: return true
case .orderedDescending: return false
case .orderedSame: continue
}
}
return false
}
}
}
The 'sorted' function compiles [and works] without problems. For 'sort' I get an error on the line that says 'sort' : "Cannot convert value of type '(_, _) -> _' to expected argument type '[SortDescriptor]'" which has me completely baffled: I do not understand where the compiler is trying to convert anything since I am passing in an array of SortDescriptors, which ought to BE an array of SortDescriptors.
Usually, this type of error means that you're handling optionals where you ought to have definite values, but since this is a function argument - and seems to work without a hitch in func sorted - all I can read from it is that 'something is wrong'. As of now, I have no idea WHAT that something is, and since we're in the early stages of beta, there is no documentation at all.
As a workaround, I have removed the sort (formerly sort-in-place) function from my code and replaced it with a dance of
let sortedArray = oldArray(sorted[...] oldArray = sortedArray
but I'd be really grateful if I could get my sort-in-place functionality back.


(array as NSArray).sortedArray(using: sortDescriptors)? There's nothing wrong with bridging to Foundation types where they provide the functionality you need.