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

CocoaheadsNL August - M2Mobi - Pragmatic MVVM

CocoaheadsNL August - M2Mobi - Pragmatic MVVM

Menno Lovink talks about using MVVM at M2Mobi

CocoaHeadsNL

August 24, 2016
Tweet

More Decks by CocoaHeadsNL

Other Decks in Technology

Transcript

  1. View Slide

  2. PRAGMATIC MVVM
    Menno Lovink

    View Slide

  3. M2MOBI
    • Native apps
    • Tons of project
    • 5 iOS developers

    View Slide

  4. AS A TEAM
    We value:
    • Being pragmatic
    • Speaking the same language

    View Slide

  5. AS A TEAM
    We want:
    • Simplicity
    • Reusability
    • Consistency
    • Flexibility

    View Slide

  6. IN THE REAL WORLD..
    We encounter:
    • Redundancy
    • Inconsistency
    • Complexity
    • Rigidness

    View Slide

  7. WE TRY TO IMPROVE
    • Experiments
    • Code reviews
    • Weekly team meetings

    View Slide

  8. MVC
    VC M
    V

    View Slide

  9. MVVM
    VM M
    V Model
    ViewModel
    View

    View Slide

  10. MVVM VS MVC
    VC M
    V
    VM M
    V

    View Slide

  11. VIEWCONTROLLER?
    VM M
    V
    VM M
    VC
    V

    View Slide

  12. MVVM EXAMPLE

    View Slide

  13. MVVM EXAMPLE
    VM M
    VC
    V

    View Slide

  14. MVVM EXAMPLE
    struct Flight {
    let flightCode: String
    let destination: String
    let origin: String
    let departureDate: NSDate
    let arrivalDate: NSDate
    }
    VM M
    VC
    V

    View Slide

  15. MVVM EXAMPLE
    class HomeViewController: UIViewController {
    var flightTileTitle:UILabel
    var flightTileSubtitle: UILabel
    var flightTileImage: UIImageView
    var viewModel: FlightViewModel
    func refresh() {
    flightTileTitle.text = viewModel.flightTileTitle
    flightTileSubtitle.text = viewModel.flightTileSubtitle
    flightTileImage.image = viewModel.flightTileImage
    }
    }
    VM M
    VC
    V

    View Slide

  16. MVVM EXAMPLE
    struct FlightViewModel {
    let model: Flight
    var flightTileTitle: String { return "naar \(model.destination)” }
    var flightTileSubtitle: String {
    let prettyDate = NSDateFormatter().stringFromDate(model.departureDate)
    return "\(model.flightCode) - \(prettyDate)"
    }
    var flightTileImage: UIImage { return UIImage(named:”IC_LeavingFlight”) }
    }
    VM M
    VC
    V

    View Slide

  17. WHAT’S IMPROVED?
    • LESS COMPLEXITY
    • IMPROVED LANGUAGE
    VM M
    VC
    V

    View Slide

  18. VIEWCONTROLLER RE-USE
    VM M
    VC
    V
    class HomeViewController: UIViewController {
    var flightTileTitle:UILabel
    var flightTileSubtitle: UILabel
    var flightTileImage: UIImageView
    var viewModel: FlightViewModel
    func refresh() {
    flightTileTitle.text = viewModel.flightTileTitle
    flightTileSubtitle.text = viewModel.flightTileSubtitle
    flightTileImage.image = viewModel.flightTileImage
    }
    }

    View Slide

  19. VIEWCONTROLLER RE-USE
    class HomeViewController: UIViewController {
    var flightTileTitle:UILabel
    var flightTileSubtitle: UILabel
    var flightTileImage: UIImageView
    var viewModel: HomeViewControllerViewModel
    func refresh() {
    flightTileTitle.text = viewModel.flightTileTitle
    flightTileSubtitle.text = viewModel.flightTileSubtitle
    flightTileImage.image = viewModel.flightTileImage
    }
    }
    VM M
    VC
    V

    View Slide

  20. VIEWCONTROLLER RE-USE
    protocol HomeViewControllerViewModel {
    var flightTileTitle: String { get }
    var flightTileSubtitle: String { get }
    var flightTileImage: UIImage { get }
    }
    class HomeViewController: UIViewController {
    var flightTileTitle:UILabel
    var flightTileSubtitle: UILabel
    var flightTileImage: UIImageView
    var viewModel: HomeViewControllerViewModel
    func refresh() {
    flightTileTitle.text = viewModel.flightTileTitle
    flightTileSubtitle.text = viewModel.flightTileSubtitle
    flightTileImage.image = viewModel.flightTileImage
    }
    }
    VM M
    VC
    V

    View Slide

  21. VIEWCONTROLLER RE-USE
    struct DepartingFlightViewModel: HomeViewControllerViewModel {
    let model: Flight
    var flightTileTitle: String { return "naar \(model.destination)” }
    var flightTileSubtitle: String {
    let prettyDate = NSDateFormatter().stringFromDate(model.departureDate)
    return "\(model.flightCode) - \(prettyDate)"
    }
    var tileImage: UIImage { return UIImage(named:”IC_LeavingFlight”) }
    }
    VM M
    VC
    V

    View Slide

  22. VIEWCONTROLLER RE-USE
    struct ArrivingFlightViewModel: HomeViewControllerViewModel {
    let model: Flight
    var flightTileTitle: String { return "van \(model.origin)” }
    var flightTileSubtitle: String {
    let prettyDate = NSDateFormatter().stringFromDate(model.arrivalDate)
    return "\(model.flightCode) - \(prettyDate)"
    }
    var tileImage: UIImage { return UIImage(named:”IC_ArrivingFlight”) }
    }
    VM M
    VC
    V

    View Slide

  23. WHAT’S IMPROVED?
    • Improved Reusability
    • Prevented complexity increase
    if(isArrivingFlight) {

    } else {

    }

    View Slide

  24. TILE RE-USE
    class HomeViewController: UIViewController {
    var flightTileTitle:UILabel
    var flightTileSubtitle: UILabel
    var flightTileImage: UIImageView
    var viewModel: HomeViewControllerViewModel
    func refresh() {
    flightTileTitle.text = viewModel.flightTileTitle
    flightTileSubtitle.text = viewModel.flightTileSubtitle
    flightTileImage.image = viewModel.flightTileImage
    }
    }
    VM M
    VC
    V

    View Slide

  25. TILE RE-USE
    class ImageTile: UIView {
    var title:UILabel
    var subTitle: UILabel
    var image: UIImageView
    var viewModel: ImageTileViewModel
    func refresh() {
    tileTitle.text = viewModel.tileTitle
    tileSubtitle.text = viewModel.tileSubtitle
    tileImage.image = viewModel.tileImage
    }
    }
    VM M
    V

    View Slide

  26. TILE RE-USE
    struct Employee {
    let firstName: String
    let lastName: String
    let profession: String
    }
    VM M
    V

    View Slide

  27. TILE RE-USE
    struct EmployeeViewModel: ImageTileViewModel {
    let model: Employee
    var tileTitle: String { return "\(model.firstName) \(model.lastName)” }
    var tileSubtitle: String { return "\(model.profession)" }
    var tileImage: UIImage { return UIImage(named:”IC_PERSON”) }
    }
    VM M
    V

    View Slide

  28. TILE RE-USE
    VM M
    VC
    V
    class HomeViewController: UIViewController {
    var flightTile: ImageTile
    var viewModel: HomeViewControllerViewModel
    func refresh() {
    flightTile.viewModel = viewModel.flightTileViewModel
    }
    }

    View Slide

  29. TILE RE-USE
    class HomeViewController: UIViewController {
    var flightTile: ImageTile
    var viewModel: HomeViewControllerViewModel
    func refresh() {
    flightTile.viewModel = viewModel.flightTileViewModel
    }
    }
    VM M
    VC
    V
    protocol HomeViewControllerViewModel {
    var flightTileViewModel: ImageTileViewModel { get }
    }

    View Slide

  30. WHAT’S IMPROVED?
    • Improved Reusability
    • Increased simplicity

    View Slide

  31. SCALABLE HIERARCHIES
    V
    V
    V

    View Slide

  32. SCALABLE HIERARCHIES
    VM
    V
    VM
    V
    VM
    V

    View Slide

  33. SCALABLE HIERARCHIES
    VM M
    V
    VM M
    V
    VM M
    V

    View Slide

  34. REUSABILITY

    View Slide

  35. REUSABILITY
    Domain
    Common
    MVVM
    VM M
    VC
    V
    MVC
    VC M
    V

    View Slide

  36. VIEWMODEL REUSABILITY

    View Slide

  37. VIEWMODEL REUSABILITY

    View Slide

  38. VIEWMODEL REUSABILITY
    struct MenuItemViewModel: HomeTileViewModel, MenuTileViewModel {
    let model: MenuItem
    var title: String { return model.Name }
    }

    View Slide

  39. RECAP
    We want:
    • Simplicity
    • Reusability
    • Consistency
    • Flexibility

    View Slide

  40. RECAP
    • Protocol Oriented MVVM
    • Closer to our goals

    View Slide

  41. WHEN WE USE MVVM?
    • Not used religiously
    • A tool for separation

    View Slide

  42. –Johnny Appleseed
    Thank You
    THANK YOU!

    View Slide