funct7
funct7

Reputation: 3601

Swift property wrapper not compiling any more in Swift 5.4+?

The following code used to work for Swift 5.2, and possibly Swift 5.3. (Last build was November 2020)

@propertyWrapper
class ActionBindable<Button> where Button : UIControl {
    
    var target: Any? {
        didSet { setTargetAction() }
    }
    
    weak var wrappedValue: Button! {
        didSet { setTargetAction() }
    }
    
    private let action: Selector
    private let event: UIControl.Event
    
    init(action: Selector, event: UIControl.Event = .touchUpInside) {
        self.action = action
        self.event = event
    }
    
    private func setTargetAction() {
        guard target != nil && wrappedValue != nil else { return }
        wrappedValue.addTarget(target, action: action, for: event)
    }
    
}

However, I'm getting an error now: Property type 'UIKit.UIControl?' does not match 'wrappedValue' type 'UIKit.UIControl?'

Haven't been following property wrappers for some time, so I'm wondering what changed.

Here is the code where the property wrapper is being used:

@ActionBindable(action: #selector(addAction))
var addButton: UIControl!

Upvotes: 2

Views: 416

Answers (1)

user652038
user652038

Reputation:

The bug we have to deal with right now is:

When wrappedValue is weak, there is no mechanism to explicitly set a type for a wrapped variable that uses the relevant property wrapper, after its name.

Your workaround is:

// ActionBindable<UIControl>
@ActionBindable(action: #selector(addAction)) var addButton
// Any subclasses:
@ActionBindable<UIButton>(action: #selector(addAction)) var addButton

However, I bet you'll have other problems, because implicitly-unwrapped optionality doesn't propagate outside of property wrappers. I bet it used to, given your addButton definition. You'll probably need a computed variable to wrap addButton then, to avoid future optional checking, which may negate the point of having a property wrapper.

Upvotes: 1

Related Questions