Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make my Objective-C class conform to Swift's `Equatable` protocol?

I have an Objective-C class (that happens to be a button, but that is not important), and at another part of my (mixed language) project, I have an array of these buttons and I'd like to get the index of a button using the find() method. Like so:

func doSomethingWithThisButtonIndex(index:Int)
{
    let buttons = [firstButton, secondButton, thirdButton]
    if index == find(buttons, firstButton)
    {
        // we've selected the first button
    }
}

but I'm getting the

Type 'ImplicitlyUnwrappedOptional' does not conform to protocol equatable

Okay, so lets go to Objective-C and have ButtonThing implement <Equatable>. But it doesn't recognize that.

So what am I to do? For now I'm building around it, forcing the array to be an NSArray and using indexOfObject. But this is ugly. And frustrating.

like image 319
Yerk Avatar asked Jun 19 '15 02:06

Yerk


People also ask

How do you conform to Equatable?

method without including a closure in each call, extend the StreetAddress type to conform to Equatable . The StreetAddress type now conforms to Equatable . You can use == to check for equality between any two instances or call the Equatable -constrained contains(_:)

How do you make a Swift protocol available in Objective C?

In order to use Swift code inside Objective-C one must scrifice some Swift features and write a wrapper around original Swift code that won't use non-compatible features (like structs, generics, enum associated values, protocol extensions etc.). All wrapper classes must inherit NSObject .

Can a protocol conform to Equatable?

Having worked through these examples and seen that trying to implement equality for protocols is fraught with possibilities of errors in some cases and just not possible in others, we can appreciate why protocols that are to be used as types cannot conform to Equatable.

Can a protocol be Equatable Swift?

In Swift, an Equatable is a protocol that allows two objects to be compared using the == operator. The hashValue is used to compare two instances. To use the hashValue , we first have to conform (associate) the type (struct, class, etc) to Hashable property.


1 Answers

First, in Swift write a custom == operator function for your class.

Second, also in Swift, write a class extension that adds the Equatable protocol conformance.

Perhaps, for example:

func == (lhs: YourClass, rhs: YourClass) -> Bool {
    // whatever logic necessary to determine whether they are equal
    return lhs === rhs
}

extension YourClass: Equatable {}

And now your class conforms to Equatable, which is Swift specific. You can not do this on the Objective-C end because you can not write custom operators for Objective-C.

like image 169
nhgrif Avatar answered Sep 19 '22 11:09

nhgrif