Deekshith Bellare Deekshith Bellare - 16 days ago 5
iOS Question

Load viewcontroller with nib using generics

Currently to load viewcontroller with same nibname I use code as follows

let recommendationVC : RecommendationVC = RecommendationVC(nibName: "RecommendationVC", bundle: nil)


I feel specifying nibname is unncessary as it is same as controller name. So i decided to use generics and infer type and nib name using generics

protocol NibIdentifiable {
static var nibNameIdentifier: String { get }
}

// MARK: - Indentifies each storyboard from its classname.
extension NibIdentifiable where Self: UIViewController {
static var nibNameIdentifier: String {
return String(describing: self)
}
}
extension UIViewController :NibIdentifiable
{

}

extension UIViewController {
func instantiate<Controller: UIViewController>(_: Controller.Type) -> Controller where Controller: NibIdentifiable {

guard let controller = Self(nibName:Controller.nibNameIdentifier,bundle:nil) as? Controller else {
fatalError("Could not dequeue cell with identifier: \(Controller.nibNameIdentifier)")
}

return controller
}
}


But on trying to create a VC instance,

let recommendationVC :RecommendationVC = UIViewController.instantiate()


receiving error
Generic parameter 'Controller' could not be inferred

What is wrong in this approach?

Answer
class Rec : UIViewController  {
    let r : String = "1231231"
}

protocol NibIdentifiable {
    static var nibNameIdentifier: String { get }
}

// MARK: - Indentifies each storyboard from its classname.
extension NibIdentifiable where Self: UIViewController {
    static var nibNameIdentifier: String {
        return String(describing: self)
    }

    static func instantiate() -> Self {

        guard let controller = Self(nibName:Self.nibNameIdentifier,bundle:nil) as? Self else {
            fatalError("Could not dequeue cell with identifier: \(Self.nibNameIdentifier)")
        }

        return controller
    }

}

extension UIViewController : NibIdentifiable {
}

let x : Rec = Rec.instantiate()

This must works.

In my case i use some Storyboardable protocol. and initiate Controller from specific storyboard.

Comments