Don't give up fighting against Apple MVC framework!
Having the module initialization code on its own Router will eliminate a bunch of code repetition, specially for huge projects.
You need to create these extensions once:
// ReusableView.swift
protocol ReusableView: class {}
extension ReusableView {
static var reuseIdentifier: String {
return String(describing: self)
}
}
// UIViewController.swift
extension UIViewController: ReusableView { }
// UIStoryboard.swift
extension UIStoryboard {
func instantiateViewController() -> T where T: ReusableView {
return instantiateViewController(withIdentifier: T.reuseIdentifier) as! T
}
}
And then, leave initialization code on the router of each VIPER module:
// MainSearchRouter.swift
class MainSearchRouter {
// MARK: Properties
weak var view: UIViewController?
// MARK: Static methods
static func setupModule() -> MainSearchViewController {
let viewController = UIStoryboard(name: MainSearchViewController.storyboardName, bundle: nil).instantiateViewController() as MainSearchViewController
let presenter = MainSearchPresenter()
let router = MainSearchRouter()
let interactor = MainSearchInteractor()
viewController.presenter = presenter
presenter.view = viewController
presenter.router = router
presenter.interactor = interactor
router.view = viewController
interactor.output = presenter
return viewController
}
}
It might seem like a lot of steps, but good news: the aforementioned plugin automates that as well!