iosswiftswift-protocolsprotocol-extension

Calling a protocol extension initializer


I'm trying to build a set of classes that would share common initializing code. Apart from inheritance, I thought protocols would be the way to go. While protocols and protocol extensions worked for me with instance and static methods, I have some troubles making it work with initializers.

Let's say we have this protocol:

protocol CloudServiceWrapper {

    static var isConfigured: Bool { get }

    init()

    func initialize()

}

Now let's say we want to add default implementations for both isConfigured and init() in a protocol extension:

extension CloudServiceWrapper {

    static var isConfigured: Bool {
        get {
            return true
        }
    }

    init() {
        print("Initializing generic CloudServiceWrapper")
        self.init()
        if Self.isConfigured {
            initialize()
        }

    }

}

Finally, let's have a class implementing this protocol and trying to benefit from its default implementations:

class OneDriveWrapper: CloudServiceWrapper {

    required init() {
        // CloudServiceWrapper() // error: protocol type 'CloudServiceWrapper' cannot be instantiated
        // self = CloudServiceWrapper.init() // error: cannot assign to value: 'self' is immutable
        // super.init() // error: 'super' members cannot be referenced in a root class
        // (self as CloudServiceWrapper).init() // error: static member 'init' cannot be used on instance of type 'CloudServiceWrapper'
        print("Initializing OneDriveWrapper")
    }

    func initialize() {
        print("Done")
    }

}

When trying to build a new instance of the OneDriveWrapper class, there's simply no way I could find to both call the class' initializer, and the default protocol implementation. And it is not possible to omit the init() in the OneDriveWrapper class, since it is required per the protocol definition, and seemingly not considered "implemented" with the protocol extension.

In fact, more broadly, I couldn't find any way to explicitly call a protocol extension's initializer, even though I know it's possible for instance methods.

What am I doing wrong? Do you know any way of combining both the class' initialiser and the protocol extension's one? Should I fall back to class inheritance instead of protocols and extensions?

Thanks!


Solution

  • An init within a protocol is required, and therefore has to be implemented explicitly i.e. a default implementation cannot be utilised.

    As for 'explicitly calling a protocol extension's initializer', you cannot instantiate a protocol type.

    I would suggest using inheritance for this.