Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to expose existing property on Obj-C class using an extension protocol in Swift

In Swift 1.1 we were able to have code like below compile and work where we exposed existing Objective-C properties through a protocol added by an extension. We also had a few where the property is handled by the extension.

@objc protocol Enableable: class {
    var enabled: Bool { get set }
}

let DisabledAlpha: CGFloat = 0.5
let EnabledAlpha: CGFloat = 1.0

extension UIButton: Enableable {}

extension UIImageView: Enableable {
    var enabled: Bool {
        get {
            return alpha > DisabledAlpha
        }
        set(enabled) {
            alpha = enabled ? EnabledAlpha : DisabledAlpha
        }
    }
}

When trying to compile this code using XCode 6.3 and Swift 1.2, we get the following error Type 'UIButton' does not conform to the protocol 'Enableable'. The UIImageView extension seems to compile fine.

Is there any way to expose these sort of existing properties from an Objective-C type or do we have to implement a proxying property with a different name?

like image 868
Michael Dubs Avatar asked Apr 13 '15 05:04

Michael Dubs


People also ask

Can Objective-C class conform to Swift protocol?

Mitrenegades solution is to use an objective-c protocol, is one way, but if you want a swift protocol, then the other would be to refactor the code so as to not use the objective-c class directly, but instead use the protocol (e.g. some protocol based factory pattern). Either way may be appropriate for your purposes.

What are the file extensions of Objective-C and Swift?

Difference is that one is for using Swift code in ObjC and the other one is for using ObjC code in Swift.

What is difference between Objective-C protocol and Swift protocol?

In Swift, calling a method will be decided at compile time and is similar to object-oriented programming, whereas in Objective C, calling a method will be decided at runtime, and also Objective C has special features like adding or replacing methods like on a class which already exists.


1 Answers

The compiler error message

note: Objective-C method 'isEnabled' provided by getter for 'enabled' does not match the requirement's selector ('enabled')

gives a hint about the problem. The enabled property of UIButton is inherited from UIControl and in Objective-C declared as

@property(nonatomic, getter=isEnabled) BOOL enabled

Therefore the protocol method has to be

@objc protocol Enableable: class {
    var enabled: Bool { @objc(isEnabled) get set }
}

and the implementation (similarly as in Swift 1.2 error on Objective-C protocol using getter):

extension UIImageView: Enableable {
    var enabled: Bool {
        @objc(isEnabled) get {
            return alpha > DisabledAlpha
        }
        set(enabled) {
            alpha = enabled ? EnabledAlpha : DisabledAlpha
        }
    }
}
like image 163
Martin R Avatar answered Oct 19 '22 19:10

Martin R