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

MVVM in iOS

Denis Lebedev
November 30, 2013

MVVM in iOS

Slides from the talk I gave at CocoaHeads Moscow 29.11.13.

Denis Lebedev

November 30, 2013
Tweet

More Decks by Denis Lebedev

Other Decks in Programming

Transcript

  1. MVVM pattern in iOS development
    Denis Lebedev,
    iOS Hipster @ Wargaming
    !
    mailto: [email protected]
    linkedin: http://linkedin.com/in/dlebedev

    View Slide

  2. View Slide

  3. Agenda
    Wargaming Service Mobile Apps dept.
    MVC
    MVVM
    Development hints
    Reference

    View Slide

  4. WARGAMING SERVICE MOBILE APPS

    View Slide

  5. SMA department
    We make apps for user engagement
    Quality really matters
    We experiment a lot with new tools & technologies

    View Slide

  6. Apps

    View Slide

  7. MODEL-VIEW-CONTROLLER

    View Slide

  8. MVC Diagram
    View
    Model
    Controller

    View Slide

  9. Classical principles
    Loose coupling
    Model is decoupled; view/controller can listen to it’s changes
    View knows about model, can manipulate controller
    Controller knows everything and “does all the things” ©

    View Slide

  10. View Controller responsibilities
    Owns & manages view’s state
    Acts as the datasource for tableviews
    Maps model’s properties to view values

    View Slide

  11. MASSIVE VIEW CONTROLLER

    View Slide

  12. Real world MVC
    Controllers are ‘almost’ not reusable
    Controllers are large
    View is very tight to it’s controller
    Controllers are hard to unit test

    View Slide

  13. Solving Massive Controller problems
    Separate object acting as tableview dataSource
    ConverterHelper, ‘MyFancyAttributeToStringHelper’, etc..

    View Slide

  14. Testing
    Unit tests of controllers code is pain
    Sort of UI tests (Calabash, KIF) is required

    View Slide

  15. Wrapping up
    MVC is not bad at all.

    View Slide

  16. Wrapping up
    What can we do for better world?

    View Slide

  17. MODEL-VIEW-VIEWMODEL

    View Slide

  18. MVVM Diagram
    View/
    ViewController
    ViewModel Model

    View Slide

  19. MVVM Diagram
    Wait what? It’s the same!

    View Slide

  20. Key differences with MVC
    ViewController owns it’s view model
    View model doesn’t know anything about controller

    View Slide

  21. Key differences with MVC
    View/ViewController
    ViewModel
    Model
    ViewController
    View
    Model
    MVC MVVM

    View Slide

  22. MVVM Models
    Can represent single domain entity or collection
    Responsible for fetching/storing data

    View Slide

  23. MVVM Views
    Cocoa note: MVVM view = view + view controller
    view is stateless
    views/view controllers become smaller

    View Slide

  24. MVVM View Models
    encapsulates all view data/properties and binds them to view
    validation logic
    actions

    View Slide

  25. ReactiveCocoa
    Functional reactive paradigm in Cocoa world
    Fancy bindings
    Composes of sync/async events of any kind
    Mature, production-ready framework

    View Slide

  26. ReactiveCocoa
    RAC(self, title) = RACObserve(self, viewModel.nickname);

    View Slide

  27. ReactiveCocoa
    RAC(self, stringType) = [RACObserve(self, model.type)
    map:^id(NSNumber *v) {
    return v.intValue == 0 ? @"zero" : @"non-zero";
    }];

    View Slide

  28. Benefits
    We don’t need to to test the UI (actually we should)
    We can implement app logic without any UI
    view model is easy testable
    view model are (almost) platform independent

    View Slide

  29. Platform agnostic code
    iPad / iPhone / OS X code sharing
    MVVM + Xamarin = shared Windows / OS X code

    View Slide

  30. How we came to MVVM
    Already familiar with ReactiveCocoa
    Strong need in good internal testing
    Fresh project developed from scratch

    View Slide

  31. DEVELOPMENT HINTS

    View Slide

  32. What actually does view controller?
    Layout
    Animations
    Device rotation
    View transitions
    !
    All sensible state is stored in view model

    View Slide

  33. Instantiation
    Every controller has viewModel property
    Some views may have separate view models
    Inject view model to controller during instantiation
    Inject view model’s important properties during instantiation

    View Slide

  34. ViewModel interface
    RACSignals as model properties where possible
    RACSignal for data requests
    Model property (NSArray, domain object, etc.)

    View Slide

  35. WPAFeaturesViewModel.h
    @interface WPAPlaneFeaturesViewModel : NSObject
    !
    @property (copy, nonatomic) NSArray *planeRows;
    !
    @property (strong, nonatomic, readonly) RACCommand *forwardCommand;
    @property (strong, nonatomic, readonly) RACSignal *forwardHidden;
    !
    @property (strong, nonatomic) RACSignal *nextPlaneTitle;
    !
    - (instancetype)initWithReferencePlane:(WOWPPlane *)plane
    classMates:(NSArray *)planes;
    !
    @end

    View Slide

  36. ViewModel for tableviews
    ViewModel has “rows” property of type NSArray
    Row is some NSObject subclass with data very coupled to cell
    Formatters, etc. are applied to row class, not cell
    Controller binds to “rows” and reloads data after property changes

    View Slide

  37. WPAPlaneRow.h
    @interface WPAPlaneRow : NSObject
    !
    @property (strong, nonatomic) WPAFeature *feature;
    @property (copy, nonatomic) NSString *value;
    @property (copy, nonatomic) NSString *grade;
    @property (copy, nonatomic) NSString *referenceGrade;
    !
    @end

    View Slide

  38. Testing
    State of model can be determined in any moment
    Property change affects view model internal state
    RACCommand changes view model state
    RACSignal pushes new state to subscribers
    ViewModel tests are very obvious and atomic:

    View Slide

  39. Real world testing
    Unit tests for view models
    Integration tests (for controllers) with KIF

    View Slide

  40. IMPERATIVE VS DECLARATIVE

    View Slide

  41. How to be functional and reactive
    Write declarative code instead of imperative
    Describe how properties are related to each other

    View Slide

  42. Functional Reactive view model
    Almost all code is in constructor
    Describes how the view should work in terms of commands and
    properties

    View Slide

  43. Functional Reactive view model
    The login button can be pressed when username and password aren’t
    blank
    !
    The error should be cleared after 5 seconds it was displayed

    View Slide

  44. REFERENCE

    View Slide

  45. Functional Reactive view model
    ReactiveCocoa https://github.com/ReactiveCocoa/ReactiveCocoa
    ReactiveViewModel https://github.com/ReactiveCocoa/
    ReactiveViewModel
    !
    FRP on iOS https://leanpub.com/iosfrp
    !
    FunctionalReactivePixels https://github.com/AshFurrow/
    FunctionalReactivePixels
    MVVMExample https://github.com/garnett/MVVMExample

    View Slide

  46. THANK YOU!

    View Slide