How can I call a static function on a protocol in a generic way?

I created another solution for this case. IMHO this is quite clean and simple.

First, create a protocol for accessing instance type.

protocol TypeAccessible {
    func type() -> Self.Type
}

extension TypeAccessible {
    func type() -> Self.Type {
        return Swift.type(of: self)
    }
}

then create your concrete class as here. The point is your protocol should conform to TypeAccessible protocol.

protocol FooProtocol: TypeAccessible {
    static func bar()
}

class Foo: FooProtocol {
    static func bar() { }
}

On call site use it as

let instance: FooProtocol = Foo()
instance.type().bar()

For further use cases, just make sure your protocols conform to TypeAccessible and that's all.


yes this is possible:

Swift 3

protocol Thing {
  static func genericFunction()
}

//... in another file

var things:[Thing] = []

for thing in things {
  type(of: thing).genericFunction()
}

Thank you @appzYourLife for the help! Your answer inspired my answer.

@appzYourLife answered my question. I had an underlying issue I was trying to resolve and the following code resolves my issue, so I'll post this here, maybe it helps someone with my same underlying question:

 protocol MyProtocol {
     static func aStaticFunc()
 }

 class SomeClassThatUsesMyProtocolButDoesntConformToIt {

     var myProtocolType: MyProtocol.Type
     init(protocolType: MyProtocol.Type) {
         myProtocolType = protocolType
     }

     func aFunction() {
         myProtocolType.aStaticFunc()
     }
 }

Nice question. Here is my humble point of view:

Is there a point to declaring a static function on a protocol?

Pretty much the same as having instance methods declared in a protocol.

The client using the protocol has to call the function on a type conforming to the protocol anyway right?

Yes, exactly like instance functions.

That breaks the idea of not having to know the type conforming to the protocol IMO.

Nope. Look at the following code:

protocol Feline {
    var name: String { get }
    static func createRandomFeline() -> Feline
    init()
}

extension Feline {
    static func createRandomFeline() -> Feline {
        return arc4random_uniform(2) > 0 ? Tiger() : Leopard()
    }
}

class Tiger: Feline {
    let name = "Tiger"
    required init() {}
}

class Leopard: Feline {
    let name = "Leopard"
    required init() {}
}

let feline: Feline = arc4random_uniform(2) > 0 ? Tiger() : Leopard()
let anotherFeline = feline.dynamicType.createRandomFeline()

I don't know the real type inside the variable feline. I just know that it does conform to Feline. However I am invoking a static protocol method.

Is there a better way to do this?

I see, you would like to call a static method/function declared in a protocol without creating a value that conforms to the protocol.

Something like this:

Feline.createRandomFeline() // DANGER: compiler is not happy now

Honestly I don't know the reason why this is not possible.