Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

WARGAMING SERVICE MOBILE APPS

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

Apps

Slide 7

Slide 7 text

MODEL-VIEW-CONTROLLER

Slide 8

Slide 8 text

MVC Diagram View Model Controller

Slide 9

Slide 9 text

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” ©

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

MASSIVE VIEW CONTROLLER

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

Wrapping up MVC is not bad at all.

Slide 16

Slide 16 text

Wrapping up What can we do for better world?

Slide 17

Slide 17 text

MODEL-VIEW-VIEWMODEL

Slide 18

Slide 18 text

MVVM Diagram View/ ViewController ViewModel Model

Slide 19

Slide 19 text

MVVM Diagram Wait what? It’s the same!

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

DEVELOPMENT HINTS

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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:

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

IMPERATIVE VS DECLARATIVE

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

REFERENCE

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

THANK YOU!