Reputation:
In the project I made with Viper, the presenter in ViewController gives a nil error. What is the reason of this? And how can I solve this problem?
AppDelegate
let wireframe = MovieWireframe()
let movies = wireframe.createMovieController()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = UINavigationController(rootViewController: movies)
window?.makeKeyAndVisible()
ViewController
Presenter here gives a nil error.
var presenter: IMoviePresenter? //Nil
override func viewDidLoad() {
super.viewDidLoad()
presenter?.startFetchingMovies() //Nil
}
Presenter
StartFetchingMovies here doesn't work because presenter is nil.
class MoviePresenter: IMoviePresenter {
var view: IMovieView?
var interactor: IMovieInteractor
var router: IMovieWireframe
var movies: MoviesResult?
init(view: IMovieView?, interactor: IMovieInteractor, router: IMovieWireframe) {
self.view = view
self.interactor = interactor
self.router = router
}
func startFetchingMovies() {
interactor.fetchMovies()
}
func showMovieController(navigationController: UINavigationController) {
router.pushToMovieDetailScreen(navigationController: navigationController)
}
}
extension MoviePresenter: IMovieInteractorDelegate {
func movieInteractorDidSuccessToFetchMovies(movies: MoviesResult) {
self.movies = movies
view?.showMovie(movies: movies)
}
func movieInteractorDidFailToFetchMovies() {
print("error")
}
}
Router
View.presenter here is not nil.
class MovieWireframe: IMovieWireframe {
func createMovieController() -> UIViewController {
print("createMovieController")
let view = MovieVC()
let movieService = APIClient()
let interactor = MovieInteractor(movieService: movieService)
let presenter = MoviePresenter(
view: view,
interactor: interactor,
router: self
)
view.presenter = presenter
print("presenter: \(presenter)")
interactor.delegate = presenter
return view
}
func pushToMovieDetailScreen(navigationController: UINavigationController) {
}
}
Upvotes: 3
Views: 597
Reputation: 902
ViewController's init completes prior to createMovieController being invoked between the 1st & 2nd lines here:
let wireframe = MovieWireframe()
let movies = wireframe.createMovieController()
For that brief interim of time, the view loaded (due to creating the wireframe) with
var presenter: IMoviePresenter?
as nil (hence why momentarily the need for the question mark there) and caused viewDidLoad to be invoked ‘prematurely’ (i.e., prior to the 2nd line being invoked). Therefore, eliminate the 2-part construction so that it is not done piecemeal 1) without MovieController then 2) finished as a 2nd step outside of the MovieWireframe construction. 1-part construction not 2-part.
Upvotes: 0