Upgrade to Pro — share decks privately, control downloads, hide ads and more …

VIPER - или то, о чем все говорят, но никто не рассказывает

Egor Tolstoy
November 18, 2015

VIPER - или то, о чем все говорят, но никто не рассказывает

VIPER - это подход к архитектуре слоя presentation iOS-приложений (то есть всеми любимых Massive View Controller'ов), основанный на разбитии логики на несколько основных составляющих с едиными ответственностями: view, presenter, interactor и router.

Выступление охватывает следующие темы:
- Структура VIPER-модуля
- Связь модулей
- Возможности, открываемые использованием VIPER

Egor Tolstoy

November 18, 2015
Tweet

More Decks by Egor Tolstoy

Other Decks in Technology

Transcript

  1. VIPER
    то, о чем все говорят, но никто
    не рассказывает

    View full-size slide

  2. Автор
    Егор Толстой
    Ведущий iOS разработчик
    Rambler&Co
    Twitter: @igrekde
    www.github.com/igrekde

    View full-size slide

  3. CompositionViewController
    @interface

    View full-size slide

  4. @interface
    [self updateContactsView];
    CompositionViewController

    View full-size slide

  5. - (void)saveMessageToDraft {
    // Crash
    }
    CompositionViewController

    View full-size slide

  6. - (void)sendMessage {
    // Crash
    }
    CompositionViewController

    View full-size slide

  7. @end
    - (void)updateAddressBook {
    // Crash
    // Crash
    // Crash
    }
    CompositionViewController

    View full-size slide

  8. - (void)updateAddressBook {
    if (invalidContacts) {
    return;
    }
    }
    @end
    CompositionViewController

    View full-size slide

  9. @interface
    CompositionViewController

    View full-size slide

  10. Хотим 100% crash-free!
    Хотим быстро и качественно!
    Хотим чистый код!
    Хотим модульность!

    View full-size slide

  11. •Структура VIPER модуля
    •Связь модулей
    •Возможности использования VIPER

    View full-size slide

  12. VIEW PRESENTER INTERACTOR
    ROUTER
    E
    E

    View full-size slide

  13. VIEW PRESENTER INTERACTOR
    ROUTER
    E
    E

    View full-size slide

  14. VIEW PRESENTER INTERACTOR
    ROUTER
    E
    E

    View full-size slide

  15. VIEW PRESENTER INTERACTOR
    ROUTER
    E
    E

    View full-size slide

  16. VIEW PRESENTER INTERACTOR
    ROUTER
    E
    E

    View full-size slide

  17. VIEW PRESENTER INTERACTOR
    ROUTER
    E
    E

    View full-size slide

  18. VIEW PRESENTER INTERACTOR
    ROUTER
    E
    E

    View full-size slide

  19. VIEW PRESENTER INTERACTOR
    ROUTER
    E
    E
    TABLEVIEW
    CELLFACTORY

    View full-size slide

  20. View Presenter Interactor Router

    View full-size slide

  21. - (void)viewDidLoad {
    [super viewDidLoad];
    }
    [self setupBarWithTitle:@"#mbltdev"];
    - (void)setupBarWithTitle:(NSString *)title {
    self.navigationItem.title = title;
    }
    View Presenter Interactor Router

    View full-size slide

  22. [self setupBarWithTitle:@"#mbltdev"];
    - (void)setupBarWithTitle:(NSString *)title {
    self.navigationItem.title = title;
    }
    View Presenter Interactor Router
    Lifecycle

    View full-size slide

  23. [self setupBarWithTitle:@"#mbltdev"];
    View Presenter Interactor Router
    Lifecycle
    Navbar Setup

    View full-size slide

  24. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events

    View full-size slide

  25. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events
    BOOL valid = [self.inputValidator
    validatePhoneNumber:phoneNumber];
    if (valid) {
    } else {
    }
    [self processToNextScreen];
    [self showErrorAlertView];

    View full-size slide

  26. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events
    if (valid) {
    } else {
    }
    [self processToNextScreen];
    [self showErrorAlertView];
    Data validation

    View full-size slide

  27. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events
    if (valid) {
    } else {
    }
    [self showErrorAlertView];
    Data validation
    [self processToNextScreen];
    Module Routing

    View full-size slide

  28. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events
    if (valid) {
    } else {
    }
    Data validation Module Routing
    [self showErrorAlertView];
    Shows data

    View full-size slide

  29. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else

    View full-size slide

  30. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else
    [rootSavingContext performBlock:^{
    Message *message =
    [Message MR_findFirst];
    }];

    View full-size slide

  31. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage

    View full-size slide

  32. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage
    NSURLSessionDataTask *dataTask =
    [self.session dataTaskWithRequest:request];
    [dataTask resume];

    View full-size slide

  33. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage
    Networking

    View full-size slide

  34. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage
    Networking
    - (void)prepareForSegue:(UIStoryboardSegue *)segue
    sender:(id)sender {
    segue.destinationViewController.inputData =
    @"inputData";
    }

    View full-size slide

  35. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage
    Networking
    Segues

    View full-size slide

  36. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage
    Networking
    - (UITableViewCell *)tableView:(UITableView *)tableView
    cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyCell *cell = [tableView dequeueReusableCell];
    [cell setupWithObject:cellObject];
    }
    Segues

    View full-size slide

  37. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage
    Networking
    Segues
    Table DataSource

    View full-size slide

  38. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage
    Networking
    - (void)panGestureRecognizerDidChangeState:(id)sender {
    CGPoint panPoint = [sender translationInView:self.view];
    self.view.frame = CGRectMake(panPoint.x,
    self.view.frame.origin.y,
    self.view.frame.size.width,
    self.view.frame.size.height);
    }
    Segues
    Table DataSource

    View full-size slide

  39. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage
    Networking
    Simple gestures
    Segues
    Table DataSource

    View full-size slide

  40. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage
    Networking
    Simple gestures
    if (panPoint.x > 100.0f) {
    }
    [self showSideMenu];
    Segues
    Table DataSource

    View full-size slide

  41. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage
    Networking
    Simple gestures
    if (panPoint.x > 100.0f) {
    }
    [self showSideMenu];
    Side Menu
    Segues
    Table DataSource

    View full-size slide

  42. View Presenter Interactor Router
    Lifecycle
    Navbar Setup
    Handles events Data validation Module Routing
    Shows data
    if-else Data storage
    Networking
    Segues
    Table DataSource
    Simple gestures
    Side Menu
    if (panPoint.x > 100.0f) {
    }
    Complex gestures

    View full-size slide

  43. VIEW PRESENTER INTERACTOR
    ROUTER
    E
    E

    View full-size slide

  44. VIEW PRESENTER INTERACTOR
    ROUTER E
    SERVICE
    SERVICE
    SERVICE
    E

    View full-size slide

  45. Роутер
    должен
    роутить

    View full-size slide

  46. VIEW PRESENTER INTERACTOR
    ROUTER E
    SERVICE
    SERVICE
    SERVICE
    E
    ASSEMBLY

    View full-size slide

  47. Экран
    =
    Модуль

    View full-size slide

  48. Экран
    =
    Модуль

    View full-size slide

  49. UIViewController
    UIView
    UITabBarController
    Daemon

    View full-size slide

  50. VIEW PRESENTER INTERACTOR
    ROUTER E
    SERVICE
    SERVICE
    SERVICE
    E
    ASSEMBLY

    View full-size slide

  51. VIEW PRESENTER INTERACTOR
    ROUTER E
    SERVICE
    SERVICE
    SERVICE
    E
    ASSEMBLY

    View full-size slide

  52. PRESENTER
    INTERACTOR
    VIEW
    ROUTER
    VIEW
    PRESENTER
    INTERACTOR
    ROUTER
    Модуль 1 Модуль 2

    View full-size slide

  53. PRESENTER
    INTERACTOR
    VIEW
    ROUTER
    VIEW
    PRESENTER
    INTERACTOR
    ROUTER
    @"Module2Segue"

    Модуль 1 Модуль 2

    View full-size slide

  54. @implementation Router
    [[self.transitionHandler openModuleUsingSegue:SegueIdentifier]
    thenChainUsingBlock:^void(id moduleInput) {
    [moduleInput moduleConfigurationMethod];
    }];
    @end

    View full-size slide

  55. MODULEVIEW
    MODULEPRESENTER
    MODULEINTERACTOR
    MODULEROUTER


    View full-size slide

  56. ~ 99% Code Coverage

    View full-size slide

  57. pod 'MyApp/Core', '1.2.2'
    pod 'MyApp/Modules/CalendarModule', '1.5'
    pod 'MyApp/Modules/SettingsModule', '1.0.1'
    pod 'SharedModules/Authorization', '2.3.4'

    View full-size slide

  58. •VIPER увеличивает тестируемость приложения,
    •VIPER увеличивает модульность приложения,
    •VIPER делает нашу жизнь немного прекраснее.

    View full-size slide

  59. One more thing...

    View full-size slide

  60. Open Source
    •Рамблер.Конференции - приложение
    •Generamba - генератор
    •VIPER McFlurry - библиотека
    •The Book of VIPER - сборник статей
    https://github.com/rambler-ios

    View full-size slide

  61. Дизайн: студия «Рамблер Инфографика»

    View full-size slide