viper architecture

45
Екатерина Коровкина Инженер-разработчик iOS наш взгляд на вопрос Архитектура VIPER

Upload: katerina-korovkina

Post on 13-Apr-2017

375 views

Category:

Mobile


0 download

TRANSCRIPT

Page 1: Viper architecture

Екатерина КоровкинаИнженер-разработчик iOS

наш взгляд на вопросАрхитектура VIPER

Page 2: Viper architecture

VIPER. Наш взгляд на вопрос

Поддержка проекта без архитектуры

Page 3: Viper architecture

VIPER. Наш взгляд на вопрос

• TDD• Code review• ???

Процесс разработки

Page 4: Viper architecture

VIPER. Наш взгляд на вопрос

MVCController

Model View

Page 5: Viper architecture

VIPER. Наш взгляд на вопрос

MVVM

ViewController ViewModel Model

Page 6: Viper architecture

VIPER. Наш взгляд на вопрос

Presenter Data Store(Entity)View Interactor

VIPERRouter

Page 7: Viper architecture

VIPER. Наш взгляд на вопрос

Что же такое «модуль»?

Page 8: Viper architecture

VIPER. Наш взгляд на вопрос

Что же такое «модуль»?

Page 9: Viper architecture

VIPER. Наш взгляд на вопрос

Что же такое «модуль»?

Page 10: Viper architecture

VIPER. Наш взгляд на вопрос

class, NSObject

UIViewController

class,NSObject

class,NSObject

NSManagedObjectNSObject,struct

View Presenter Interactor Data Store(Entity)

Router

VIPER

Page 11: Viper architecture

VIPER. Наш взгляд на вопрос

Конфигурация модуля

Page 12: Viper architecture

VIPER. Наш взгляд на вопрос

Запуск конфигурации модуля

class MoviesListModuleInitializer: NSObject {

override func awakeFromNib() {

let configurator = factory.moduleConfigurator() configurator.configureModule(self.viewController) }}

Page 13: Viper architecture

VIPER. Наш взгляд на вопрос

Конфигурацияclass MoviesListModuleConfigurator { func configureModule(viewController: ViewController) {

let presenter = Presenter() let service = ServiceDefault()

… viewController.presenter = presenter presenter.builder = builder

… }}

Page 14: Viper architecture

VIPER. Наш взгляд на вопрос

let controller = UIViewController(data: data)let controller = UIViewController()controller.data = data

Проблема: Не хотим отказываться от Segue

Передача данных между модулями

Page 15: Viper architecture

VIPER. Наш взгляд на вопрос

Есть же метод

prepareForSegue

Page 16: Viper architecture

VIPER. Наш взгляд на вопрос

class BaseViewController: UIViewController, ModuleDataTransferProtocol {

func performSegueWithIdentifier(identifier: String, configurationBlock: (destination: ConfigurableController) -> Void) {

… } func prepareForSegue(segue: UIStoryboardSegue,

sender: AnyObject?) {

var destination = segue.destinationViewController block(destination: destination) }}

Базовый контроллер

Page 17: Viper architecture

VIPER. Наш взгляд на вопрос

Открытие модуля func openMovieWithId(movieId: String) {

controller.performSegueWith(block: { destinationController in

destinationController.configureModule(movieId) })

}

Page 18: Viper architecture

VIPER. Наш взгляд на вопрос

Схема передачи данныхrouter.openMoviewWithId(id)

vC.performSegueWithBlock(…)

prepareForSegue(…)

configurationBlock(destination)

Page 19: Viper architecture

VIPER. Наш взгляд на вопрос

Дополнительные соглашения

• NSManagedObject не дальше интерактора• Service Oriented Architecture (SOA) за интерактором• Общие части в pod’ы

Page 20: Viper architecture

VIPER. Наш взгляд на вопрос

Пример экранаVIPER + Swift

Page 21: Viper architecture

VIPER. Наш взгляд на вопрос

Пример модуля

Page 22: Viper architecture

VIPER. Наш взгляд на вопрос

Viewprotocol MoviesListViewInput: class {

func showData(dataStructure: DataStructure)

func showError(error: NSError)

func showEmptyView()}

Page 23: Viper architecture

VIPER. Наш взгляд на вопрос

Presenter// Данные от вьюшкиprotocol MoviesListViewOutput {

func viewIsReadyToAppear()

func didSelectMovieWithIndex(index: Int)}

// Данные от интерактораprotocol MoviesListInteractorOutput: class {

func didObtainMoviesList(movies: [Movie]?)

func didFailToObtainMoviesListWithError(error: NSError)}

Page 24: Viper architecture

VIPER. Наш взгляд на вопрос

Interactor

//Получение данных для модуляprotocol MoviesListInteractorInput {

func obtainMoviesList()

}

Page 25: Viper architecture

VIPER. Наш взгляд на вопрос

Router// Открытие другого экранаprotocol MoviesListRouterInput {

func openMovieWithId(movieId: String)}

Page 26: Viper architecture

VIPER. Наш взгляд на вопрос

Конкретнее

View

Presenter

Interactor

Service

viewIsReadyToAppear()

obtainData()

fetchData()

Page 27: Viper architecture

VIPER. Наш взгляд на вопрос

Все идет хорошоService

Interactor

Presenter

completionBlock()Array <Objects>

didObtainData()Array <Objects>

Page 28: Viper architecture

VIPER. Наш взгляд на вопрос

Отображаем данные

Presenter

View

showData()

Page 29: Viper architecture

VIPER. Наш взгляд на вопрос

Все идет плохо

Service

Interactor

Presenter

View

completionBlock()Error

didFailWithError()

showError()

Page 30: Viper architecture

VIPER. Наш взгляд на вопрос

Пример экранаVIPER + Swift

Page 31: Viper architecture

VIPER. Наш взгляд на вопрос

Viewprotocol WriteUsViewInput: class {

func showEmailError()

func clearInputViews()

func showSpinner()

func hideSpinner() }

Page 32: Viper architecture

VIPER. Наш взгляд на вопрос

Presenterprotocol WriteUsOutput: class {

func userRequestToWriteUs(withName name: String, email: String, message: String)

func userWantsToGoBack(areFieldsEmpty: Bool)}

protocol WriteUsInteractorOutput: class { func didSendFeedbackMessage() func didFailToSendFeedbackMessage(error: NSError)}

Page 33: Viper architecture

VIPER. Наш взгляд на вопрос

Interactorprotocol WriteUsInteractorInput {

func isValidEmail(email: String) -> Bool

func sendMessage(fromAuthor username: String, email: String, message: String)

}

Page 34: Viper architecture

VIPER. Наш взгляд на вопрос

Routerprotocol WriteUsRouterInput: class {

func goBackFromViewController(viewController: UIViewController)

func showAlertExitSubmitAlert(actionHandler: AlertActionsHandler)

func showAlertFeedbackSendDidSucceed()

func showAlertFeedbackSendDidFail()}

Page 35: Viper architecture

VIPER. Наш взгляд на вопрос

Конкретнее

View

Presenter

Interactor

userRequestToWriteUs()

isValidEmail()

Page 36: Viper architecture

VIPER. Наш взгляд на вопрос

Все идет хорошоPresenter

Interactor

Service

sendMessage()

sendMessage()

Page 37: Viper architecture

VIPER. Наш взгляд на вопрос

Отображаем данные

Presenter

Router

showFeedbackSucceed()

Page 38: Viper architecture

VIPER. Наш взгляд на вопрос

Ввод не валиден Presenter

View

showEmailError()

Page 39: Viper architecture

VIPER. Наш взгляд на вопрос

Что получается

Presenter ServiceView Interactor

Router Local storage

Networkclient

Page 40: Viper architecture

VIPER. Наш взгляд на вопрос

Достоинства• Быстрый вход в новый проект• Приемлемый код даже у новичков• Легкое переиспользование созданных компонент• Легкая модификация/поддержка кода

Page 41: Viper architecture

VIPER. Наш взгляд на вопрос

Недостатки• Большое количество времени• Большое количество кода• Большое количество интеграционных тестов• Холивары на тему «Где должен быть такой-то код?»

Page 42: Viper architecture

VIPER. Наш взгляд на вопрос

А нужен ли VIPER?/// Контролер для отображения информации о

приложенииclass AboutViewController: UIViewController {

//Текст текущей версии приложения @IBOutlet weak var versionLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() let versionNumber = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") let buildNumber = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleVersion") versionLabel.text = "Версия \(versionNumber!) (\(buildNumber!))" }

/** Метод для открытия нашей странички в iTunes */ @IBAction func openAppstore(sender: AnyObject) { UIApplication.sharedApplication().openURL(NSURL(string: "https://itunes.apple.com/ru/app/lenta.ru-vse-novosti-dna-politika/id975805914?mt=8")!) }}

Page 43: Viper architecture

VIPER. Наш взгляд на вопрос

Выводы

• Длинные по времени проекты

• Необходимость подключения новых людей в середине проекта

Стоит использовать Не стоит использовать

• Рекламное приложение/визитка/прототипирование

• Стартап, когда нужно выпустить MVP как можно быстрее

Page 44: Viper architecture

VIPER. Наш взгляд на вопрос

Open Source• Рамблер.Конференции — приложение• Generamba —  генератор• VIPER McFlurry —  библиотека• The Book of VIPER — сборник статей

https://github.com/rambler-ios

Page 45: Viper architecture

VIPER. Наш взгляд на вопрос

THANKS!