Ведущий выдает нулевую ошибку в проекте VIPER

#ios #swift #viper-architecture

Вопрос:

В проекте, который я сделал с Viper, ведущий в ViewController выдает нулевую ошибку. В чем причина этого? И как я могу решить эту проблему?

AppDelegate

 let wireframe = MovieWireframe()
let movies = wireframe.createMovieController()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = UINavigationController(rootViewController: movies)
window?.makeKeyAndVisible()
 

Контроллер просмотра

Ведущий здесь выдает нулевую ошибку.

 var presenter: IMoviePresenter? //Nil
   
override func viewDidLoad() {
  super.viewDidLoad()

  presenter?.startFetchingMovies() //Nil 
}

 

Ведущий

StartFetchingMovies здесь не работает, потому что ведущий равен нулю.

 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")
    }
}
 

Маршрутизатор

View.presenter здесь не равен нулю.

 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) {
        
        
    }
}
 

Комментарии:

1. пожалуйста, добавьте код вместо скриншотов

2. @TejaNandamuri, можешь проверить еще раз?

Ответ №1:

Инициализация ViewController завершается до вызова createMovieController между 1-й и 2-й строками здесь:

 let wireframe = MovieWireframe()
let movies = wireframe.createMovieController()
 

За этот короткий промежуток времени представление загрузилось (из-за создания каркаса) с

 var presenter: IMoviePresenter?
 

как ноль (следовательно, почему на мгновение возникла необходимость в вопросительном знаке) и вызвал вызов viewDidLoad «преждевременно» (т. Е. до вызова 2-й строки). Поэтому исключите конструкцию из 2 частей, чтобы она не выполнялась по частям 1) без MovieController, а затем 2) была завершена как 2-й шаг за пределами конструкции MovieWireframe. конструкция из 1 части,а не из 2 частей.