Olimjon Kenjaev
Olimjon Kenjaev

Reputation: 39

UIStoryboard extension

I'm attempting to create a storyboard extension in swift in order to safer instantiate view controllers

protocol IdentifierType {
     typealias Identifier: RawRepresentable
}

extension IdentifierType where Self: UIStoryboard, Identifier.RawValue == String  {

    func instantiateViewControllerWithIdentifier(identifier:Identifier) -> UIViewController {
        return self.instantiateViewControllerWithIdentifier(identifier.rawValue)
    }

}

And It will not make any errors in compile time. However, when I try to implement it like:

extension UIStoryboard : IdentifierType {
    enum Identifier: String {
        case MainViewController = "MAIN_VIEW_CONTROLLER"
        case ContactUsViewController = "CONTACT_US_VIEW_CONTROLLER"
        case AboutViewController = "ABOUT_VIEW_CONTROLLER"
    }
}

The compile time error occurs. "'Identifier' is ambituous for type lookup in this context"

Upvotes: 0

Views: 1179

Answers (1)

beyowulf
beyowulf

Reputation: 15331

You can say something like:

protocol IdentifierType {
    associatedtype Identifier: RawRepresentable
}

extension UIStoryboard : IdentifierType {
    enum Identifier: String {
        case MainViewController = "MAIN_VIEW_CONTROLLER"
        case ContactUsViewController = "CONTACT_US_VIEW_CONTROLLER"
        case AboutViewController = "ABOUT_VIEW_CONTROLLER"
    }

    func instantiateViewControllerWithIdentifier(identifier:Identifier) -> UIViewController {
        return self.instantiateViewControllerWithIdentifier(identifier.rawValue)
    }
}

You can then call something like self.storyboard?.instantiateViewControllerWithIdentifier(.ContactUsViewController) which is what you want.

Not sure what the benefit of having RawRepresentable in this case, maybe you can explain why you think you need to use that.

But assuming this is everything you need, the protocol IdentifierType is completely unnecessary, so you can simplify to:

extension UIStoryboard  {
    enum Identifier: String {
        case MainViewController = "MAIN_VIEW_CONTROLLER"
        case ContactUsViewController = "CONTACT_US_VIEW_CONTROLLER"
        case AboutViewController = "ABOUT_VIEW_CONTROLLER"
    }

    func instantiateViewControllerWithIdentifier(identifier:Identifier) -> UIViewController {
        return self.instantiateViewControllerWithIdentifier(identifier.rawValue)
    }
}

You can find discussion of removing hard coded strings with enums in swift here and here.

Upvotes: 1

Related Questions