Aleksander Zubala
Aleksander Zubala

Reputation: 141

Pure Swift class conforming to protocol with static method - issue with upcasting

Given we have a Swift protocol with one static method:

protocol Creatable: class {
    static func create() -> AnyObject
}

and a pure Swift class which conforms to the protocol:

class Foo : Creatable {
    static func create() -> AnyObject {
        return Foo() as AnyObject
    }
}

Later on when one tries to make use of that protocol by operating on type Creatable e.g.:

var f : Creatable = Foo.self
f.create()

The compiler complains with the following:

error: type 'Foo.Type' does not conform to protocol 'Creatable'

The question is: is this a Swift limitation or I'm using the protocols and static/class method in the wrong way.

Objective-C equivalent would be something like:

Class someClass = [Foo class];
if ([someClass conformsToProtocol:@protocol(Creatable)]) {
    [(Class <Foo>)someClass create];
}

Upvotes: 13

Views: 8803

Answers (2)

Jerry
Jerry

Reputation: 4480

Using .Type is the key:

var f : Creatable.Type = Foo.self

And this no longer gives the "unimplemented" error. See full code below:

protocol Creatable: class {
    static func create() -> AnyObject
}

class Foo : Creatable {
    static func create() -> AnyObject {
        return Foo() as AnyObject
    }
}

var f : Creatable.Type = Foo.self
f.create()

Upvotes: 8

Airspeed Velocity
Airspeed Velocity

Reputation: 40973

A Creatable reference points to an instance of Foo, not to the Foo type itself.

To get the equivalent of the class-level protocol implementation, you need an instance of Creatable.Type:

let c: Creatable.Type = Foo.self

However, you’ll get an error when you then try to use it:

// error: accessing members of protocol type value 'Creatable.Type' is unimplemented
c.create()

All that said, is there a reason why you can’t just use functions to fulfill your requirement, instead of metatypes?

let f = Foo.create
// f is now a function, ()->AnyObject, that creates Foos
let someFoo = f()

Upvotes: 9

Related Questions