Search code examples
swifthashable

Swift 5: How to make a Set containing Class Types (for NSXPCInterface)


In Apple documentation of NSXPCInterface.setClasses(_:for:argumentIndex:ofReply:), for Swift, the first parameter is described as:

An NSSet containing Class objects —for example, [MyObject class].

Hmmm, it looks as though someone neglected to update this from Objective-C to Swift. For Swift I presume it should be something like

A Set containing Class Types

(Someone please correct my wording.) But how do you make a Set containing Class Types? The compiler will not allow me to declare a Set whose member types are not do not conform to Hashable. This makes sense because hashes are needed to maintain uniqueness among members. But Class Types in Swift do not seem to be hashable. Try this in any Swift file, or a playground…

class Foo {}
let mySet: Set<AnyHashable>
mySet.insert(Foo)

The compiler complains:

Argument type 'Foo.Type' does not conform to expected type 'Hashable'

Or, more broadly, does anyone know how to use NSXPCInterface.setClasses(_:for:argumentIndex:ofReply:) in Swift 5?


Solution

  • The classes you pass need to be @objc classes (and subclasses of NSObject). You'll put them into an NSSet, and then cast that to Set:

    let classSet = NSSet(object: Foo.self) as! Set<AnyHashable>
    

    This is almost certainly a bug in NSXPCInterface (it needs some kind of "refine for Swift" or possibly a shim), and I suggest opening a defect at bugreport.apple.com.