Search code examples
swiftgenericsparameter-passingfunc

How to pass type as func argument?


When trying to describe routing procedure in order to make VC more lean I faced a problem. When passing type as func argument I get a compile error

Cannot find type 'destinationType' in scope

in the following code. Please have a look and explain what am I doing wrong way.

extension MainViewController {
    
    func route<T: UIViewController>(to destinationType: T.Type) {
        let identifier = String(describing: destinationType)
        guard let destinationViewController = self.storyboard?.instantiateViewController(identifier: identifier) as? destinationType else {
            return
        }
        present(destinationViewController, animated: true)
    }
    
}

Solution

  • Nothing in your code relies upon the type of the view controller that comes from the storyboard. So you don't need a type, a generic, or any of the other accoutrements. All you need is the identifier, and you can say "fetch that view controller and present it":

    extension UIViewController {
        func route(to identifier: String) {
            guard let destinationViewController = self.storyboard?.instantiateViewController(identifier: identifier) else { return }
            present(destinationViewController, animated: true)
        }
    }
    

    However, if you insist on the generic and the cast, the type you are looking for is not destinationType (which is a metatype, not a type at all) — it's T:

    extension UIViewController {
        func route<T>(to destinationType: T.Type) where T : UIViewController {
            let identifier = String(describing: destinationType)
            guard let destinationViewController = self.storyboard?.instantiateViewController(identifier: identifier) as? T else { return }
            present(destinationViewController, animated: true)
        }
    }