Using a model view-view model architecture for iOS apps

Using a Model-View-ViewModel
architecture for iOS Apps
Allan Shih
Agenda
● Problems of MVC
● Introduction to Model-View-ViewModel (MVVM)
○ Model
○ View
○ Controller
○ View Model
○ Data Manager
● Implementation
● Reference
Model-View-Controller
● A proven pattern for organizing code in complex
application design
● Separates an application into three main logical
components: model, view, and controller
Realistic Cocoa MVC
● Cocoa MVC encourages you to write Massive View Controllers,
because they are so involved in View’s life cycle that it’s hard to
say they are separate.
Problems of MVC
● MVC frameworks tend to lead to Apps with
Massive View Controllers
● Network calls, persistence, view logic, and all
other sorts of code ends up in the Controller.
● This Makes Controller code
○ difficult to read
○ difficult to change
○ difficult to unit test
○ difficult to reuse
Model-View-ViewModel (MVVM)
● The MVVM treats the view controller as the View
● There is no tight coupling between the View and
the Model
Model
● The same responsibility as in MVC
● Used to represent a “model” of some set of data
● For example: a model of a date, event, or place
● This typically involves having an NSObject class file
with properties
○ Hold data about the model object
○ Possibly some business logic around that model object.
View
● Used to represent the user interface (UI) of the app
● This can include UIViews, UIButtons, UITableViewCells,
UICollectionViewCells and UIViews on a storyboard
● A view shouldn’t directly interact with data model objects
○ It should instead have a function that takes in a set of parameters
representing data
Controller
● Used to set up the UI of views and handle any user
interaction with these views
● Like views, the controller shouldn’t directly interact with
the data model objects
○ It should ask its view model to set up a view with data instead.
○ Any state and business logic of the view controller will be kept by its
view model
View model
● Used to represent a model of a view controller
● All state and business logic associated with a view
controller will be kept by its view model
● A view model will trigger all calls to send and receive
data (using data managers)
● The view model doesn’t know about the view controller
Data manager
● Used to make and handle all calls to get data
● JSON parsing and serialization of this data to data
model objects
● Cache data
● Hold any state related to the data
● A view model will trigger the data manager to make and
handle data calls
Implementation
Data manager
class DataManager {
static let sharedInstance: DataManager = DataManager()
func getData(callback : ((result : [DataObject])->()){
//code to get data i.e. some rest call
//parse JSON and serialize to an array of data model objects
//return array of data model objects by calling the callback
parameter
callback(result: result)
}
}
View Model - Init
class ViewModel {
var reloadCollectionViewCallback : (()->())!
var dataArray = [DataObject]()
init(reloadCollectionViewCallback : (()->()) {
self.reloadCollectionViewCallback = reloadCollectionViewCallback
retrieveData()
}
...
}
View Model - Retrieve Data
class ViewModel {
var reloadCollectionViewCallback : (()->())!
var dataArray = [DataObject]()
...
func retrieveData(){
DataManager.SharedInstance.getData({ result in
self.dataArray = result
self.reloadCollectionViewCallback()
}
}
}
View Controller - Init View Model
class ViewController: UIViewController {
var viewModel : ViewModel!
override func viewDidLoad(){
super.viewDidLoad()
setupCollectionView()
viewModel = ViewModel(reloadCollectionViewCallback :
reloadCollectionViewData)
}
}
View Controller - Setup and Reload Collection View
class ViewController: UIViewController {
...
func setupColllectionView() {
collectionView.delegate = self
collectionView.dataSource = self
}
func reloadCollectionViewData() {
collectionView.reloadData()
}
}
View Controller - UICollectionViewDataSource
extension ViewController: UICollectionViewDataSource {
func numberOfSectionsInCollectionView(collectionView:
UICollectionView) -> Int {
return viewModel.numberOfSectionsInCollectionView()
}
func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return viewModel.numberOfItemsInSection(section)
}
}
View Controller - Setup Collection View Cell
extension ViewController: UICollectionViewDataSource {
...
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) ->
UICollectionViewCell {
return viewModel.setUpCollectionViewCell(indexPath,
collectionView : collectionView)
}
}
View Model - Number of Items in Sections
// class ViewModel {
var dataArray : [DataObject]!
let kNumberOfSectionsInCollectionView = 1
func numberOfItemsInSection(section : Int) -> Int {
return dataArray.count
}
func numberOfSectionsInCollectionView() -> Int {
return kNumberOfSectionsInCollectionView
}
//}
View Model - Set up the collection view cell
// class ViewModel {
func setUpCollectionViewCell(indexPath : NSIndexPath, collectionView :
UICollectionView) -> UICollectionViewCell {
let dataObject = dataArray[indexPath.row]
let cell =
collectionView.dequeueReusableCellWithReuseIdentifier(“cell”,
forIndexPath: indexPath) as! MyCollectionViewCell
cell.setupData(name: dataObject.name, address: dataObject.address)
return cell
}
View - Collection view cell
class MyCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var addressLabel: UILabel!
func setupData(name : String?, address: String?){
nameLabel.text = name ?? “”
addressLabel.text = address ?? “”
}
}
ViewController - Keep track of the index path of the selected cell
extension ViewController: UICollectionViewDelegate {
func collectionView(collectionView: UICollectionView,
didSelectItemAtIndexPath indexPath: NSIndexPath) {
viewModel.setSelectedCellIndexPath(indexPath)
performSegue(WithIdentifier: “toNextViewController”, sender:
self)
}
}
ViewController - Segue to a new view controller
//class ViewController: UIViewController {
override func prepareForSegue(segue: UIStoryboardSegue, sender:
AnyObject?) {
if segue.identifier == “toNextViewController” {
let nextVC = segue.destinationViewController as!
NextViewController
nextVC.viewModel =
viewModel.getNextViewControllerViewModel()
}
}
//}
View Model - The index path of the selected cell
//class ViewModel : NSObject {
var selectedCellIndexPath : NSIndexPath!
...
func setSelectedCellIndexPath(indexPath : NSIndexPath) {
selectedCellIndexPath = indexPath
}
//}
View Model - Initialize the next view controller’s view model
//class ViewModel : NSObject {
func getNextViewControllerViewModel() ->
NextViewControllerViewModel {
let dataObject = dataArray[selectedCellIndexPath]
let nextViewControllerViewModel =
NextViewControllerViewModel(dataObject: dataObject)
return nextViewControllerViewModel
}
//}
Summery
● The view controller should only be responsible for
displaying UI and handling user interaction.
● Business logic, state, and data handling should be taken
out of the view controller and put into the view controller’s
view model.
● Only view models and data managers are allowed to
directly touch data model objects
○ view controllers and views should not.
Demo
Reference
● The Swift Programming Language (Swift 3.0.1)
● Swift and Model-View-ViewModel in Practice
● Swift Tutorial: An Introduction to the MVVM Design Pattern
● MVVM in Swift
1 de 29

Recomendados

iOS architecture patternsiOS architecture patterns
iOS architecture patternsallanh0526
508 visualizações22 slides
Mvvm basicsMvvm basics
Mvvm basicsanusha kadimi
1K visualizações14 slides
Why MVC?Why MVC?
Why MVC?Wayne Tun Myint
10.5K visualizações23 slides
GUI patterns : My understandingGUI patterns : My understanding
GUI patterns : My understandingNitin Bhide
564 visualizações16 slides

Mais conteúdo relacionado

Mais procurados

Introduction to ASP.NET MVCIntroduction to ASP.NET MVC
Introduction to ASP.NET MVCSunpawet Somsin
4.1K visualizações19 slides
ASP .Net MVC 5ASP .Net MVC 5
ASP .Net MVC 5Nilachal sethi
719 visualizações15 slides
[@NaukriEngineering] MVVM in iOS[@NaukriEngineering] MVVM in iOS
[@NaukriEngineering] MVVM in iOSNaukri.com
309 visualizações10 slides

Mais procurados(20)

Introduction to ASP.NET MVCIntroduction to ASP.NET MVC
Introduction to ASP.NET MVC
Sunpawet Somsin4.1K visualizações
Sexy Architecting. VIPER: MVP on steroidsSexy Architecting. VIPER: MVP on steroids
Sexy Architecting. VIPER: MVP on steroids
Dmytro Zaitsev1.7K visualizações
ASP .Net MVC 5ASP .Net MVC 5
ASP .Net MVC 5
Nilachal sethi719 visualizações
[@NaukriEngineering] MVVM in iOS[@NaukriEngineering] MVVM in iOS
[@NaukriEngineering] MVVM in iOS
Naukri.com309 visualizações
MV(C, mvvm) in iOS and ReactiveCocoaMV(C, mvvm) in iOS and ReactiveCocoa
MV(C, mvvm) in iOS and ReactiveCocoa
Yi-Shou Chen1.3K visualizações
Angular js anupamaAngular js anupama
Angular js anupama
Anupama Prabhudesai30 visualizações
Introduction of angular jsIntroduction of angular js
Introduction of angular js
Tamer Solieman1.8K visualizações
Viper architectureViper architecture
Viper architecture
*instinctools915 visualizações
ASP.NET MVC 3ASP.NET MVC 3
ASP.NET MVC 3
Buu Nguyen6.2K visualizações
Itroducing Angular JSItroducing Angular JS
Itroducing Angular JS
Carlos Emanuel Mathiasen485 visualizações
From mvc to viperFrom mvc to viper
From mvc to viper
Krzysztof Profic11.2K visualizações
Angular JS IndtrodutionAngular JS Indtrodution
Angular JS Indtrodution
adesh2123 visualizações
KnockOutjs from ScratchKnockOutjs from Scratch
KnockOutjs from Scratch
Udaya Kumar626 visualizações
What's new in asp.net mvc 4What's new in asp.net mvc 4
What's new in asp.net mvc 4
Simone Chiaretta8.5K visualizações
Introduction to WPF and MVVMIntroduction to WPF and MVVM
Introduction to WPF and MVVM
Sirar Salih1.5K visualizações
Asp.net MVC training sessionAsp.net MVC training session
Asp.net MVC training session
Hrichi Mohamed6.3K visualizações
Angular js presentation at DatacomAngular js presentation at Datacom
Angular js presentation at Datacom
David Xi Peng Yang1.1K visualizações

Similar a Using a model view-view model architecture for iOS apps

ASP .net MVCASP .net MVC
ASP .net MVCDivya Sharma
5.4K visualizações26 slides
MVVM & Data Binding Library MVVM & Data Binding Library
MVVM & Data Binding Library 10Clouds
2.3K visualizações31 slides
Backbone.jsBackbone.js
Backbone.jsOmnia Helmi
1.5K visualizações33 slides

Similar a Using a model view-view model architecture for iOS apps(20)

Sitecore MVC (London User Group, April 29th 2014)Sitecore MVC (London User Group, April 29th 2014)
Sitecore MVC (London User Group, April 29th 2014)
Ruud van Falier915 visualizações
Sitecore MVC (User Group Conference, May 23rd 2014)Sitecore MVC (User Group Conference, May 23rd 2014)
Sitecore MVC (User Group Conference, May 23rd 2014)
Ruud van Falier3.9K visualizações
ASP .net MVCASP .net MVC
ASP .net MVC
Divya Sharma5.4K visualizações
Optimize CollectionView ScrollingOptimize CollectionView Scrolling
Optimize CollectionView Scrolling
Andrea Prearo1K visualizações
MVVM & Data Binding Library MVVM & Data Binding Library
MVVM & Data Binding Library
10Clouds2.3K visualizações
Backbone.jsBackbone.js
Backbone.js
Omnia Helmi1.5K visualizações
Swift Tableview iOS App DevelopmentSwift Tableview iOS App Development
Swift Tableview iOS App Development
Ketan Raval1.1K visualizações
Say bye to Fragments with Conductor & KotlinSay bye to Fragments with Conductor & Kotlin
Say bye to Fragments with Conductor & Kotlin
Miquel Beltran Febrer594 visualizações
MVC.pptxMVC.pptx
MVC.pptx
ssuserfd27a76 visualizações
Asp.Net MvcAsp.Net Mvc
Asp.Net Mvc
micham3.1K visualizações
ASP.NET MVC Controllers & ActionsASP.NET MVC Controllers & Actions
ASP.NET MVC Controllers & Actions
onsela4.3K visualizações
Spring Web MVCSpring Web MVC
Spring Web MVC
zeeshanhanif10.6K visualizações
Controllers & actionsControllers & actions
Controllers & actions
Eyal Vardi834 visualizações
AngularJS.part1AngularJS.part1
AngularJS.part1
Andrey Kolodnitsky401 visualizações
Chapter4.pptxChapter4.pptx
Chapter4.pptx
narendrakumar4063361 visão
MVC architectureMVC architecture
MVC architecture
Emily Bauman1.8K visualizações

Mais de allanh0526

WebpWebp
Webpallanh0526
32 visualizações15 slides
Digital authenticationDigital authentication
Digital authenticationallanh0526
51 visualizações28 slides
Integration of slather and jenkinsIntegration of slather and jenkins
Integration of slather and jenkinsallanh0526
574 visualizações40 slides
Unit testing in xcode 8 with swiftUnit testing in xcode 8 with swift
Unit testing in xcode 8 with swiftallanh0526
272 visualizações68 slides
Ui testing in xcodeUi testing in xcode
Ui testing in xcodeallanh0526
609 visualizações43 slides

Mais de allanh0526(17)

WebpWebp
Webp
allanh052632 visualizações
Digital authenticationDigital authentication
Digital authentication
allanh052651 visualizações
Integration of slather and jenkinsIntegration of slather and jenkins
Integration of slather and jenkins
allanh0526574 visualizações
Unit testing in xcode 8 with swiftUnit testing in xcode 8 with swift
Unit testing in xcode 8 with swift
allanh0526272 visualizações
Ui testing in xcodeUi testing in xcode
Ui testing in xcode
allanh0526609 visualizações
How to work with dates and times in swift 3How to work with dates and times in swift 3
How to work with dates and times in swift 3
allanh05261.7K visualizações
ThingMaker in SwiftThingMaker in Swift
ThingMaker in Swift
allanh0526115 visualizações
Automatic reference counting in SwiftAutomatic reference counting in Swift
Automatic reference counting in Swift
allanh052695 visualizações
Core data in SwfitCore data in Swfit
Core data in Swfit
allanh0526114 visualizações
From android/java to swift (3)From android/java to swift (3)
From android/java to swift (3)
allanh052690 visualizações
From android/ java to swift (2)From android/ java to swift (2)
From android/ java to swift (2)
allanh052655 visualizações
From android/java to swift (1)From android/java to swift (1)
From android/java to swift (1)
allanh052650 visualizações
WebRTCWebRTC
WebRTC
allanh0526120 visualizações
Pipeline interfacePipeline interface
Pipeline interface
allanh052688 visualizações
Deploying artifacts to archivaDeploying artifacts to archiva
Deploying artifacts to archiva
allanh0526968 visualizações
Android httpclientAndroid httpclient
Android httpclient
allanh0526528 visualizações

Último(20)

Web Dev - 1 PPT.pdfWeb Dev - 1 PPT.pdf
Web Dev - 1 PPT.pdf
gdsczhcet49 visualizações
TE Connectivity: Card Edge InterconnectsTE Connectivity: Card Edge Interconnects
TE Connectivity: Card Edge Interconnects
CXL Forum95 visualizações
Micron CXL product and architecture updateMicron CXL product and architecture update
Micron CXL product and architecture update
CXL Forum23 visualizações
MemVerge: Memory Viewer SoftwareMemVerge: Memory Viewer Software
MemVerge: Memory Viewer Software
CXL Forum117 visualizações
Future of Learning - Yap Aye Wee.pdfFuture of Learning - Yap Aye Wee.pdf
Future of Learning - Yap Aye Wee.pdf
NUS-ISS37 visualizações
The Research Portal of Catalonia: Growing more (information) & more (services)The Research Portal of Catalonia: Growing more (information) & more (services)
The Research Portal of Catalonia: Growing more (information) & more (services)
CSUC - Consorci de Serveis Universitaris de Catalunya59 visualizações
CXL at OCPCXL at OCP
CXL at OCP
CXL Forum203 visualizações
Future of Learning - Khoong Chan MengFuture of Learning - Khoong Chan Meng
Future of Learning - Khoong Chan Meng
NUS-ISS31 visualizações
Spesifikasi Lengkap ASUS Vivobook Go 14Spesifikasi Lengkap ASUS Vivobook Go 14
Spesifikasi Lengkap ASUS Vivobook Go 14
Dot Semarang34 visualizações
Business Analyst Series 2023 -  Week 3 Session 5Business Analyst Series 2023 -  Week 3 Session 5
Business Analyst Series 2023 - Week 3 Session 5
DianaGray1094 visualizações

Using a model view-view model architecture for iOS apps

  • 2. Agenda ● Problems of MVC ● Introduction to Model-View-ViewModel (MVVM) ○ Model ○ View ○ Controller ○ View Model ○ Data Manager ● Implementation ● Reference
  • 3. Model-View-Controller ● A proven pattern for organizing code in complex application design ● Separates an application into three main logical components: model, view, and controller
  • 4. Realistic Cocoa MVC ● Cocoa MVC encourages you to write Massive View Controllers, because they are so involved in View’s life cycle that it’s hard to say they are separate.
  • 5. Problems of MVC ● MVC frameworks tend to lead to Apps with Massive View Controllers ● Network calls, persistence, view logic, and all other sorts of code ends up in the Controller. ● This Makes Controller code ○ difficult to read ○ difficult to change ○ difficult to unit test ○ difficult to reuse
  • 6. Model-View-ViewModel (MVVM) ● The MVVM treats the view controller as the View ● There is no tight coupling between the View and the Model
  • 7. Model ● The same responsibility as in MVC ● Used to represent a “model” of some set of data ● For example: a model of a date, event, or place ● This typically involves having an NSObject class file with properties ○ Hold data about the model object ○ Possibly some business logic around that model object.
  • 8. View ● Used to represent the user interface (UI) of the app ● This can include UIViews, UIButtons, UITableViewCells, UICollectionViewCells and UIViews on a storyboard ● A view shouldn’t directly interact with data model objects ○ It should instead have a function that takes in a set of parameters representing data
  • 9. Controller ● Used to set up the UI of views and handle any user interaction with these views ● Like views, the controller shouldn’t directly interact with the data model objects ○ It should ask its view model to set up a view with data instead. ○ Any state and business logic of the view controller will be kept by its view model
  • 10. View model ● Used to represent a model of a view controller ● All state and business logic associated with a view controller will be kept by its view model ● A view model will trigger all calls to send and receive data (using data managers) ● The view model doesn’t know about the view controller
  • 11. Data manager ● Used to make and handle all calls to get data ● JSON parsing and serialization of this data to data model objects ● Cache data ● Hold any state related to the data ● A view model will trigger the data manager to make and handle data calls
  • 13. Data manager class DataManager { static let sharedInstance: DataManager = DataManager() func getData(callback : ((result : [DataObject])->()){ //code to get data i.e. some rest call //parse JSON and serialize to an array of data model objects //return array of data model objects by calling the callback parameter callback(result: result) } }
  • 14. View Model - Init class ViewModel { var reloadCollectionViewCallback : (()->())! var dataArray = [DataObject]() init(reloadCollectionViewCallback : (()->()) { self.reloadCollectionViewCallback = reloadCollectionViewCallback retrieveData() } ... }
  • 15. View Model - Retrieve Data class ViewModel { var reloadCollectionViewCallback : (()->())! var dataArray = [DataObject]() ... func retrieveData(){ DataManager.SharedInstance.getData({ result in self.dataArray = result self.reloadCollectionViewCallback() } } }
  • 16. View Controller - Init View Model class ViewController: UIViewController { var viewModel : ViewModel! override func viewDidLoad(){ super.viewDidLoad() setupCollectionView() viewModel = ViewModel(reloadCollectionViewCallback : reloadCollectionViewData) } }
  • 17. View Controller - Setup and Reload Collection View class ViewController: UIViewController { ... func setupColllectionView() { collectionView.delegate = self collectionView.dataSource = self } func reloadCollectionViewData() { collectionView.reloadData() } }
  • 18. View Controller - UICollectionViewDataSource extension ViewController: UICollectionViewDataSource { func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { return viewModel.numberOfSectionsInCollectionView() } func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return viewModel.numberOfItemsInSection(section) } }
  • 19. View Controller - Setup Collection View Cell extension ViewController: UICollectionViewDataSource { ... func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { return viewModel.setUpCollectionViewCell(indexPath, collectionView : collectionView) } }
  • 20. View Model - Number of Items in Sections // class ViewModel { var dataArray : [DataObject]! let kNumberOfSectionsInCollectionView = 1 func numberOfItemsInSection(section : Int) -> Int { return dataArray.count } func numberOfSectionsInCollectionView() -> Int { return kNumberOfSectionsInCollectionView } //}
  • 21. View Model - Set up the collection view cell // class ViewModel { func setUpCollectionViewCell(indexPath : NSIndexPath, collectionView : UICollectionView) -> UICollectionViewCell { let dataObject = dataArray[indexPath.row] let cell = collectionView.dequeueReusableCellWithReuseIdentifier(“cell”, forIndexPath: indexPath) as! MyCollectionViewCell cell.setupData(name: dataObject.name, address: dataObject.address) return cell }
  • 22. View - Collection view cell class MyCollectionViewCell: UICollectionViewCell { @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var addressLabel: UILabel! func setupData(name : String?, address: String?){ nameLabel.text = name ?? “” addressLabel.text = address ?? “” } }
  • 23. ViewController - Keep track of the index path of the selected cell extension ViewController: UICollectionViewDelegate { func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { viewModel.setSelectedCellIndexPath(indexPath) performSegue(WithIdentifier: “toNextViewController”, sender: self) } }
  • 24. ViewController - Segue to a new view controller //class ViewController: UIViewController { override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == “toNextViewController” { let nextVC = segue.destinationViewController as! NextViewController nextVC.viewModel = viewModel.getNextViewControllerViewModel() } } //}
  • 25. View Model - The index path of the selected cell //class ViewModel : NSObject { var selectedCellIndexPath : NSIndexPath! ... func setSelectedCellIndexPath(indexPath : NSIndexPath) { selectedCellIndexPath = indexPath } //}
  • 26. View Model - Initialize the next view controller’s view model //class ViewModel : NSObject { func getNextViewControllerViewModel() -> NextViewControllerViewModel { let dataObject = dataArray[selectedCellIndexPath] let nextViewControllerViewModel = NextViewControllerViewModel(dataObject: dataObject) return nextViewControllerViewModel } //}
  • 27. Summery ● The view controller should only be responsible for displaying UI and handling user interaction. ● Business logic, state, and data handling should be taken out of the view controller and put into the view controller’s view model. ● Only view models and data managers are allowed to directly touch data model objects ○ view controllers and views should not.
  • 28. Demo
  • 29. Reference ● The Swift Programming Language (Swift 3.0.1) ● Swift and Model-View-ViewModel in Practice ● Swift Tutorial: An Introduction to the MVVM Design Pattern ● MVVM in Swift