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

MVVM in iOS

C4edd51fe88b9820a046db724d53fd91?s=47 Denis Lebedev
November 30, 2013

MVVM in iOS

Slides from the talk I gave at CocoaHeads Moscow 29.11.13.

C4edd51fe88b9820a046db724d53fd91?s=128

Denis Lebedev

November 30, 2013
Tweet

Transcript

  1. MVVM pattern in iOS development Denis Lebedev, iOS Hipster @

    Wargaming ! mailto: d_lebedev@wargaming.net linkedin: http://linkedin.com/in/dlebedev
  2. None
  3. Agenda Wargaming Service Mobile Apps dept. MVC MVVM Development hints

    Reference
  4. WARGAMING SERVICE MOBILE APPS

  5. SMA department We make apps for user engagement Quality really

    matters We experiment a lot with new tools & technologies
  6. Apps

  7. MODEL-VIEW-CONTROLLER

  8. MVC Diagram View Model Controller

  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” ©
  10. View Controller responsibilities Owns & manages view’s state Acts as

    the datasource for tableviews Maps model’s properties to view values …
  11. MASSIVE VIEW CONTROLLER

  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
  13. Solving Massive Controller problems Separate object acting as tableview dataSource

    ConverterHelper, ‘MyFancyAttributeToStringHelper’, etc..
  14. Testing Unit tests of controllers code is pain Sort of

    UI tests (Calabash, KIF) is required
  15. Wrapping up MVC is not bad at all.

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

  17. MODEL-VIEW-VIEWMODEL

  18. MVVM Diagram View/ ViewController ViewModel Model

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

  20. Key differences with MVC ViewController owns it’s view model View

    model doesn’t know anything about controller
  21. Key differences with MVC View/ViewController ViewModel Model ViewController View Model

    MVC MVVM
  22. MVVM Models Can represent single domain entity or collection Responsible

    for fetching/storing data
  23. MVVM Views Cocoa note: MVVM view = view + view

    controller view is stateless views/view controllers become smaller
  24. MVVM View Models encapsulates all view data/properties and binds them

    to view validation logic actions
  25. ReactiveCocoa Functional reactive paradigm in Cocoa world Fancy bindings Composes

    of sync/async events of any kind Mature, production-ready framework
  26. ReactiveCocoa RAC(self, title) = RACObserve(self, viewModel.nickname);

  27. ReactiveCocoa RAC(self, stringType) = [RACObserve(self, model.type) map:^id(NSNumber *v) { return

    v.intValue == 0 ? @"zero" : @"non-zero"; }];
  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
  29. Platform agnostic code iPad / iPhone / OS X code

    sharing MVVM + Xamarin = shared Windows / OS X code
  30. How we came to MVVM Already familiar with ReactiveCocoa Strong

    need in good internal testing Fresh project developed from scratch
  31. DEVELOPMENT HINTS

  32. What actually does view controller? Layout Animations Device rotation View

    transitions ! All sensible state is stored in view model
  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
  34. ViewModel interface RACSignals as model properties where possible RACSignal for

    data requests Model property (NSArray, domain object, etc.)
  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
  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
  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
  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:
  39. Real world testing Unit tests for view models Integration tests

    (for controllers) with KIF
  40. IMPERATIVE VS DECLARATIVE

  41. How to be functional and reactive Write declarative code instead

    of imperative Describe how properties are related to each other
  42. Functional Reactive view model Almost all code is in constructor

    Describes how the view should work in terms of commands and properties
  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
  44. REFERENCE

  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
  46. THANK YOU!