0

Circumstances

The following class:

class User {
    var name = "Max"
    var surname = "Mustermann"
}

and the following protocol:

protocol Sharable {
    func share(name: String)
    var isSharable: Bool { get set }
}

Intention

Extend the protocol sharable in a way so that subclasses of User get an implemented version of share(:) and isSharable.

The following extension attempts to do this:

extension Sharable where Self: User {
    func share(name: String) { print(name) }
    var isSharable: Bool { return !name.isEmpty }
}

Where the problem occurs

The created subclass Admin should get all functionality of Sharable for free without storing and implementing variables and functions.

class Admin: User, Sharable {
    
}

But Xcode will print the error:

'Admin' does not conform to protocol 'Sharable'

Xcode proposes the following:

class Admin: User, Sharable {
    var isSharable: Bool
}

Now Xcode prints the error:

class 'Admin' has no initializers

Question

Is there a way to extend the protocol Sharable so that Admin has a variable isSharable without defining or initializing it? Basically like it works with the function share(:), which has not to be implemented by the subclass because it is implemented by the extension.

Desired Call site

class ArbitraryObject: User, Sharable {
    // no implementation or initializing of isSharable or share(:)
}


let arbitraryObject = ArbitraryObject()
if arbitraryObject.isSharable {
    arbitraryObject.share(name: arbitraryObject.name)
}
WalterBeiter
  • 2,021
  • 3
  • 23
  • 48

1 Answers1

3

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 }
}
Andrew
  • 26,706
  • 9
  • 85
  • 101