Extension to Array<Element>???

Is it possible to extend the swift native Array struct? There's no method on Array to sort by an NSSortDescriptor (bug 27723091 - Everyone go open your own bug on this please!) so I was hoping to do something like this:


extension Array {
    func sorted(descriptors: [NSSortDescriptor]) -> [Element] {
        return (self as NSArray).sortedArray(using: descriptors)
    }
}


But that doesn't work as "Cannot convert value of type 'Array<Element>' to type 'NSArray' in coersion"

Answered by OOPer in 160779022

Sorry, I have been missing that when Array.Element is a descendent of NSObject, it does not conform to `_ObjectiveCBridgeable`.


You may need another extension like this:

extension Array where Element: NSObject {
    func sorted(descriptors: [NSSortDescriptor]) -> [Element] {
        return (self as NSArray).sortedArray(using: descriptors) as! [Element]
    }
}


I'm not sure these two extensions cover whole use cases of yours. Please tell me how these work, or how these do not work.

You know, not all Swift Arrays can be converted to NSArray.


You may need to write something like this:

extension Array where Element: _ObjectiveCBridgeable {
    func sorted(descriptors: [NSSortDescriptor]) -> [Element] {
        return (self as NSArray).sortedArray(using: descriptors) as! [Element]
    }
}

Thanks! I know it's kinda silly to make that extension for a one-line thing, but it makes me feel better getting all those "as NSArray" casts out of the rest of my code 🙂

Actually...this doesn't work 😟 The _ObjectiveCBridgeable isn't matching so the sorted method doesn't appear on my arrays.

Accepted Answer

Sorry, I have been missing that when Array.Element is a descendent of NSObject, it does not conform to `_ObjectiveCBridgeable`.


You may need another extension like this:

extension Array where Element: NSObject {
    func sorted(descriptors: [NSSortDescriptor]) -> [Element] {
        return (self as NSArray).sortedArray(using: descriptors) as! [Element]
    }
}


I'm not sure these two extensions cover whole use cases of yours. Please tell me how these work, or how these do not work.

This one definitely works when the class does in fact come from NSObject. Any thoughts on how I'd cover a simple struct or class that doesn't?

NSPredicate works on NSObjects, with utilizing the KVC feature of Objective-C runtime. So, it would be very hard to make them work on pure Swift classes or Swift structs. I recommend you to work with closure based sorting methods in such cases.

It's not always an option. If you're working with sources related to an NSTableView, for example, your table has sort descriptors built in. I can probably get away with NSObject though since most of the cases will relate to Core Data objects.

Extension to Array&lt;Element&gt;???
 
 
Q