2

I'm trying to get the class name from within a class method in an extension. Is this possible? I end up with "DRHT" as the name of the class

extension

extension UIViewController {

    public class func instanceFromStoryboard(storyboardIdentifier: String = "Main") -> UIViewController {
        let storyboard = UIStoryboard(name: storyboardIdentifier, bundle: nil)
        let controllerIdentifier = NSStringFromClass(self)
        return storyboard.instantiateViewControllerWithIdentifier(controllerIdentifier) as UIViewController
    }

}

Usage

let homeViewController = HomeViewController.instanceFromStoryboard()
aryaxt
  • 76,198
  • 92
  • 293
  • 442
  • I don't know why you're getting just a "DRHT", but keep in mind that in Swift, NSStringFromClass() will return a string of the format: moduleName.ClassName. So if your identifier is "ClassName", you might have to do some parsing on the return of NSStringFromClass() – dominostars Jan 11 '15 at 18:04
  • @dominostars Somehow cleaning the project and running it again worked also changed to ```NSStringFromClass(toType).pathExtension``` – aryaxt Jan 11 '15 at 18:18

2 Answers2

1

I ended up doing it differently to make it more type-safe and eliminate casting.

extension UIStoryboard {

    public class func instantiateViewController <T: UIViewController>(type: T.Type, storyboardIdentifier: String = "Main") -> T {
        let storyboard = UIStoryboard(name: storyboardIdentifier, bundle: nil)
        return storyboard.instantiateViewController(type)
    }

    public func instantiateViewController <T: UIViewController>(type: T.Type) -> T {
        return instantiateViewControllerWithIdentifier(String(type)) as! T
    }

}

extension UIViewController {

    public class func instantiateFromStoryboard(storyboardName: String = "Main") -> Self {
        return UIStoryboard.instantiateViewController(self, storyboardIdentifier: storyboardName)
    }
}

Usage

let vc = UIStoryboard.instantiateViewController(HomeViewController.self)

or

let vc = UIStoryboard.instantiateViewController(HomeViewController.self, storyboardIdentifier: "Storybaord_Name")

or

let vc = storyboard.instantiateViewController(HomeViewController.self)

or

let vc = HomeViewController.instantiateViewController()
aryaxt
  • 76,198
  • 92
  • 293
  • 442
-1

Thanks to MartinR and his answer, I know the answer:

extension UIViewController
{
    class func instantiateFromStoryboard() -> Self
    {
        return instantiateFromStoryboardHelper(self, storyboardName: "Main")
    }

    class func instantiateFromStoryboard(storyboardName: String) -> Self
    {
        return instantiateFromStoryboardHelper(self, storyboardName: storyboardName)
    }

    private class func instantiateFromStoryboardHelper<T>(type: T.Type, storyboardName: String) -> T
    {
        var storyboardId = ""
        let components = "\(type.dynamicType)".componentsSeparatedByString(".")

        if components.count > 1
        {
            storyboardId = components[1]
        }
        let storyboad = UIStoryboard(name: storyboardName, bundle: nil)
        let controller = storyboad.instantiateViewControllerWithIdentifier(storyboardId) as! T

        return controller
    }
}

Usage:

let vc = HomeViewController.instantiateFromStoryboard()
Community
  • 1
  • 1
ChikabuZ
  • 10,031
  • 5
  • 63
  • 86