Swift: setting an optional property of a protocol
It's impossible in Swift (yet?). Referenced from an ADF thread:
Optional property requirements, and optional method requirements that return a value, will always return an optional value of the appropriate type when they are accessed or called, to reflect the fact that the optional requirement may not have been implemented.
So it's no surprise to get optional values easily. However, setting a property requires implementation to be guaranteed.
I'd consider making an extension returning your default value for keyboardType
, and having the setter do nothing.
extension UITextInputTraits {
var keyboardType: UIKeyboardType {
get { return .default }
set { /* do nothing */ }
}
}
That way you can remove the optional
from your property declaration.
protocol UITextInputTraits : NSObjectProtocol {
var keyboardType: UIKeyboardType { get set }
}
Or, if you prefer, you can make it of optional return type, var keyboardType: UIKeyboardType?
, and return nil
instead of .Default
in your extension.
This way, you can test for myObject.keyboardType == nil
to see if your property is implemented.
One workaround is to create another protocol that conforms to the first one, but that declare that optional property as mandatory. Then to try to cast the object as that new protocol, and if the cast succeed, we can access the property directly.
protocol UITextInputTraitsWithKeyboardType : UITextInputTraits {
// redeclare the keyboardType property of the parent protocol, but this time as mandatory
var keyboardType: UIKeyboardType { get set }
}
func initializeTextInputTraits(textInputTraits: UITextInputTraits) {
// We try to cast ('as?') to the UITextInputTraitsWithKeyboardType protocol
if let traitsWithKBType = textInputTraits as? UITextInputTraitsWithKeyboardType {
// if the cast succeeded, that means that the keyboardType property is implemented
// so we can access it on the casted variable
traitsWithKBType.keyboardType = .Default
}
// (and if the cast failed, this means that the property is not implemented)
}
I also demonstrated that at the bottom on this SO answer if you want another example of the idea.