How can we call class functions with a dynamic class name?
Assume the following example where I have two class with methods with same signature
class Foo{
   class func doSomething()
}
class Foobar {
   class func doSomething()
}
class ActualWork{
   //call following method with a variable type so that it accepts dynamic class  name
   func callDynamicClassMethod(x: dynamicClass)
    x.doSomething() 
  }
How can this be implemented so that x accepts values at run time
Edit: Sorry, I missed to mention that I was looking for any other ways other than protocol oriented approach. This is more of an exploratory question to explore if there is a more direct approach/pods/libraries to achieve this.
I liked this question, because it made me to think a lit'bit outside of the box.
I'll answer it, by dividing it into a few parts.
First
call class functions
Class function is basically a Type methods, which can be achieved using the static word inside the class context.
Taking that into account, you can get a simple solution, using protocol and passing the class reference (conforming to that protocol) like this:
protocol Aaa{
   static func doSomething();
}
class Foo : Aaa{
  static func doSomething() {
    print("Foo doing something");
  }
}
class FooBar : Aaa{
  static func doSomething() {
    print("FooBar doing something");
  }
}
class ActualWork{
  //Using class (static) method
  func callDynamicClassMethod <T: Aaa> (x: T.Type) {
    x.doSomething();
  }
}
//This is how you can use it
func usage(){
    let aw = ActualWork();
    aw.callDynamicClassMethod(x: Foo.self);
    aw.callDynamicClassMethod(x: Foo.self);
}
Second
In case you don't really need the method on the class context, you may consider using instance methods. In that case the solution would be even simpler, like this:
protocol Bbb{
  func doSomething();
}
class Bar : Bbb{
  func doSomething() {
    print("Bar instance doing something");
  }
}
class BarBar : Bbb{
  func doSomething() {
    print("BarBar instance doing something");
  }
}
class ActualWork{
  //Using instance (non-static) method
  func callDynamicInstanceMethod <T: Bbb> (x: T){
    x.doSomething();
  }
}
//This is how you can use it
func usage(){
   let aw = ActualWork();
    aw.callDynamicInstanceMethod(x: Bar());
    aw.callDynamicInstanceMethod(x: BarBar());
}
Third
If you need to use the class func syntax, as OP originally did:
class func doSomething()
You CANNOT simply use a protocol. Because protocol is not a class... So compiler won't allow it.

But it's still possible, you can achieve that by using Selector with NSObject.perform method
like this:
class ActualWork : NSObject{
    func callDynamicClassMethod<T: NSObject>(x: T.Type, methodName: String){
        x.perform(Selector(methodName));
    }
}
class Ccc : NSObject{
    @objc class func doSomething(){
        print("Ccc class Doing something ");
    }
}
class Ddd : NSObject{
    @objc class func doSomething(){
        print("Ccc class Doing something ");
    }
    @objc class func doOther(){
        print("Ccc class Doing something ");
    }
}
//This is how you can use it
func usage() {
    let aw = ActualWork();
    aw.callDynamicClassMethod(x: Ccc.self, methodName: "doSomething");
    aw.callDynamicClassMethod(x: Ddd.self, methodName: "doSomething");
    aw.callDynamicClassMethod(x: Ddd.self, methodName: "doOther");
}
                        Generics and Protocol oriented programming will do the job:
protocol Doable {
    static func doSomething()
}
class Foo: Doable {
    static func doSomething() {
        debugPrint("Foo")
    }
}
class Foobar: Doable {
    static func doSomething() {
        debugPrint("Foobar")
    }
}
class ActualWork {
    func callDynamicClassMethod<T: Doable>(x: T.Type) {
        x.doSomething()
    }
}
let work = ActualWork()
work.callDynamicClassMethod(x: Foo.self)
work.callDynamicClassMethod(x: Foobar.self)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With