how to extend a swift protocol with an extension so that classes get an implemented variable defined by the protocol
Currently your protocol defines isSharable
as { get set }
protocol Sharable {
func share(name: String)
var isSharable: Bool { get set }
}
This means that when you construct your extension it is not actually conforming to the protocol
extension Sharable where Self: User {
func share(name: String) { print(name) }
var isSharable: Bool { return !name.isEmpty }
}
This is due to the fact that you have defined isSharable
in your extension as a computed property. Computed properties are get
only.
You can make your extension conform to the Sharable
protocol by removing the set
requirement. So your protocol would become:
protocol Sharable {
func share(name: String)
var isSharable: Bool { get }
}
Implement protocol through extension
Cocoa is written in Objective-C. Objective-C can't see Swift protocol extension code. So it's unaware of that implementation of imagePickerController:didFinishPickingImage:
. If you want a delegate method to be called by Cocoa, you need to put it where Cocoa can see it.
swift protocol extension default implementation vs actual implementation in class
Having a default implementation for a required protocol function/property means that your conforming types won't have to implement that function/property, they can use the default implementation instead.
However, if a conforming type does implement the function/property, then the compiler will always call the more specific implementation, namely the one in your conforming class and not the default one.
So even if you stored an instance of MyClass2
in a variable of type MyProtocol
, you'd still get the MyClass2
implementation when accessing the property on the variable.
let myClass2: MyProtocol = MyClass2()
type(of: myClass2).name // "Specific name"
The behaviour is different for non-required properties/functions declared and defined in a protocol extension. If you declare a property/function in the protocol extension only, then even if you provide a different implementation for that in a conforming class, you won't be able to access that implementation from a variable whose type is the protocol type rather than the specific conforming type.
protocol MyProtocol {
static var name: String { get }
}
extension MyProtocol {
static var name: String {
return "unnamed"
}
// Optional protocol requirement
static var nonRequired: String {
return "nonRequired"
}
}
// does not specify its own name
class MyClass: MyProtocol { }
//specifies its own name!
class MyClass2: MyProtocol {
static var name: String {
return "Specific name"
}
// Specific implementation
static var nonRequired: String {
return "Specific"
}
}
let myClass = MyClass()
MyClass.name
let myClass2: MyProtocol = MyClass2()
type(of: myClass2).name // "Specific name"
type(of: myClass2).nonRequired // "nonRequired"
MyClass2.nonRequired // "Specific"
How does protocol extension work in Swift?
I don't think there is even a need to inherit from NSObject
if you are making a BaseClass
to be inherited by other classes.
You can simply add classTag
in the BaseClass
itself, i.e.
class BaseClass {
var classTag: String {
return String(describing: type(of: self))
}
}
class SubClass: BaseClass {
func someFunc() {
print(self.classTag)
}
}
Another option can be to use protocol
and protocol extension
and provide the default definition of classTag
, i.e.
protocol SomeProtocol {
var classTag: String { get }
}
extension SomeProtocol {
var classTag: String {
return String(describing: type(of: self))
}
}
Then, you can conform SomeProtocol
to the classes wherever required, i.e.
class SubClass: SomeProtocol {
func someFunc() {
print(self.classTag)
}
}
In any case, inheriting from NSObject
is unnecessary since you don't need any NSObject
specific functionality for that.
Related Topics
How Set Custom Fonts for iOS13 Context Menu Actions
How to Add Icon to a Share Sheet in Swift
Tapping an Mkmapview in Swiftui
How to Calculate the Energy Per Bin in a Dft
How to Use Spritekit Archives with Skspritenode Subclasses
Using "Codable" to Set Property Values Doesn't Work Through Inheritance
Convert [(Key: String, Value: String)] in [String:String]
How to Properly Check If Non-Optional Return Value Is Valid
Swiftui: How to Only Run Code When the User Stops Typing in a Textfield
Sort Dictionary Keys by Value, Then by Key
Why Can't I Use Subscripting on a Ckrecord Object in Swift
If-Let Any to Rawrepresentable<String>
Animate an Skspritenode with Textures That Have a Size Different from the Original
Swift Realm: After Writing Transaction Reference Set to Nil
Swiftui [Bug] Navigationview and List Not Showing on iPad Simulator Only