UIKit + Viper или MVC здорового человека

Автор: admin от 25-04-2017, 09:45, посмотрело: 554

Около года назад я познакомился с таким замечательным паттерном, как Viper. И теперь хочу рассказать о своих проблемах, а так же об их решении.

Введение


Начитавшись туториолов о Viper я начал пробовать создать на нем новый проект. В итоге мой Viper выглядел примерно так:

UIKit + Viper или MVC здорового человека

Рядом с каждым блоком подписан базовый класс. Стрелками обозначены ссылки между объектами (пунктиром — weak).

Данная схема не решает крайне важную проблему. Каким образом располагать модули в UINavigationController? Из-за того, что стек навигации необходимо добавлять наследников класса UIViewController.


  • придется в router протягивать view через presenter и явно указывать, что это UIViewController

  • после добавления view в UINavagationController, у view счетчик сильных связей увеличится до 2-х. В последствии придется вручную убирать из памяти viper модуль.


В таком подходе очевидна некоторая несовместимость Viper и UIKit.

Как подружить Viper и UIKit


В первую очередь необходимо понять, как перейти от Apple MVC к Viper. MVC достаточно легко раскладывается на view, presenter и interactor. Но у viper появляется еще дополнительный слой — router. И на этом моменте я предлагаю альтернативную точку зрения(во всяком случае на просторах интернета я ничего подобного не видел).

UIKit + Viper или MVC здорового человека

Стало заметно больше UI компонентов. Теперь давайте разберемся, почему здесь все так, ну или почти. В качестве основы для своих рассуждений, я воспользуюсь данной статьей.

В ней сказано:
Presenter/Презентатор

Presenter — это PONSO, который в основном состоит из логики, чтобы управлять UI. Он собирает входные данные от взаимодействия с пользователем, таким образом, он может отправлять запросы Interactor'у. Presenter также получает результаты Interactor'а и преобразовывать результаты в состояние, которое является наиболее эффективным для отображения на View.

Entity никогда не передаются из Interactor'а к Presenter'у. Вместо этого простые структуры данных, у которых нет поведения, передаются из Interactor'а к Presenter'у. Это препятствует любой ‘реальной работе’ в Presenter'е. Presenter может только подготовить данные для отображения на View.

Если в качестве presenter взять не PONSO, а UIViewController, что изменится? Да presenter начнет отвечать за отображение модуля, но только под капотом UIKit. Все методы жизненного цикла, можно расценивать по такому же принципу, как события от кнопок view. То есть view сообщает presenter, что случился viewdidload и с этим можно что-то сделать. Вся логика отрисовки осталась на view.

Теперь давайте рассмотрим router(в статье изображен, как wireframe. Я обычно разделяю на router и moduleManager)

Wireframe/Каркас

Маршрутизация обрабатывает навигацию от одного экрана к другому, как определено в wireframes, созданных проектировщиком взаимодействия. Wireframe объект несет ответственность за маршрутизацию. Wireframe объект владеет объектами UIWindow, UINavigationController, и т.д. Он ответственен за создание Interactor, Presenter и View/ViewController и за настройки ViewController. Так как Presenter содержит логику, чтобы реагировать на ввод данных пользователем, Presenter знает, когда перейти на другой экран. Wireframe знает, как это сделать. Итак, Presenter — это пользователь Wireframa.

Встает вопрос. Почему router не может сам являться UINavigationController? Зачем нам еще велосипед, когда в UIKit есть свои роутеры — это UINavigationController и сочувствующие. В подобных классах уже заложена основная логика.

Что решает такой подход?


  • меньше кода, все сделано за нас

  • понятный код, для человека, незнакомого с Viper

  • за работу с памятью теперь отвечает UIKit, руками не придется уничтожать модули

  • простая интеграция со сторонними библиотеками, которые на входе принимают UIViewController


В качестве примера я создал небольшой демо проект. Надеюсь на объективную дискуссию.

Источник: Хабрахабр

Категория: Веб-разработка / iOS

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
  • bowtiesmilelaughingblushsmileyrelaxedsmirk
    heart_eyeskissing_heartkissing_closed_eyesflushedrelievedsatisfiedgrin
    winkstuck_out_tongue_winking_eyestuck_out_tongue_closed_eyesgrinningkissingstuck_out_tonguesleeping
    worriedfrowninganguishedopen_mouthgrimacingconfusedhushed
    expressionlessunamusedsweat_smilesweatdisappointed_relievedwearypensive
    disappointedconfoundedfearfulcold_sweatperseverecrysob
    joyastonishedscreamtired_faceangryragetriumph
    sleepyyummasksunglassesdizzy_faceimpsmiling_imp
    neutral_faceno_mouthinnocent