In this article,
MVVM stands for "Model View ViewModel". MVVM isn't a design pattern. It’s a software architecture often
Lets talk about the Differences between Architecture and design patterns.
- Design pattern focuses on low-level details of the application, not heigh level details, so it's safe to say that architecture pattern only focuses on heigh level details.
- Architecture comes in the Designing phase and Design Patterns come in the Building phase.
- An architectural pattern is like a blueprint and a design pattern is the actual implementation.
- Architecture is base on which everything else adhere to and design pattern is a way to structure classes to solve common problems.
- All Architecture is a design pattern but all design patterns can't be architecture. Like MVC can come under both. But singleton design pattern can't be an architecture pattern. MVC, MVVM all come under both.
Choosing the right architecture pattern for your project Whenever we get a new project, what we have to think about is a lot of things, which is basically the first thing we think about.
- Project Requirements: What are the project requirements? What this project does, basically high level requirements.
- Project complexity: considering the requirement. We calculate the complexity of what is the hidden complexity or known complexity of the project.
- Project Deadline: This is set by the client i.e. the client wants an application and wants the application to be done in 4-5 months.
- Architectural Patterns for Project: Now, comes the architecture of the project. The architecture of the project is determined by the complexity of the project's requirements, that is, considering the requirements and complexity, we think that this architectural pattern is the most appropriate for the project.
When should I use MVVM
- Don't use MVVM for small project.
- Use MVVM for moderately complex application.
- moderately complex- project that are between 4-6 months duration and require 4-10 team member.
Advantages of MVVM
- Business logic is decoupled from Ul
- Easy to maintain and test
- Easy to reuse components
- Loosely coupled architecture: MWM makes your application architecture as loosely coupled.
- Internal implementation to be chnaged without affecting the others.
- You can write unit test cases for both the viewmodel and Model layer without the need to reference the View.
// // Constant.swift // MVVM_Example // // Created by Rathaur on 02/07/20. // Copyright © 2020 AppCodeZip. All rights reserved. // import Foundation struct EndPoint { static let strUrl = "https://jsonplaceholder.typicode.com/posts" }
// // User.swift // MVVM_Example // // Created by Rathaur on 02/07/20. // Copyright © 2020 AppCodeZip. All rights reserved. // import Foundation class User : Codable{ var userId : Int? var id : Int? var title : String? var body : String? }
// // UserViewModel.swift // MVVM_Example // // Created by Rathaur on 02/07/20. // Copyright © 2020 AppCodeZip. All rights reserved. // import Foundation class UserViewModel{ typealias completionBlock = ([User]) -> () var apiHandler = APIHandler() var datasourceArray = [User]() func getDataFromAPIHandlerClass(url: String, completionBlock : @escaping completionBlock){ apiHandler.getDataFromApi(withUrl: url) { [weak self] (arrUser) in self?.datasourceArray = arrUser completionBlock(arrUser) } } func getNumberOfRowsInSection() -> Int{ return datasourceArray.count } func getUserAtIndex(index : Int) -> User{ let user = datasourceArray[index] return user } func getCellData(index : Int) -> String{ let user = self.getUserAtIndex(index: index) let userId = user.userId ?? 0 let id = user.id ?? 0 // let body = user.body ?? "" let title = user.title ?? "" let res = "UserId- \(userId)" + " " + "ID- \(id)" + " " + "Title- \(title)" return res } func getDetailCellData(index : Int) -> String { let user = self.getUserAtIndex(index: index) let body = user.body ?? "" let detailRes = "Body- \(body)" return detailRes } }
// APIHandler.swift // MVVM_Example // // Created by Rathaur on 02/07/20. // Copyright © 2020 AppCodeZip. All rights reserved. // import Foundation class APIHandler{ typealias completionBlock = ([User]) -> () func getDataFromApi(withUrl strUrl : String, completionBlock : @escaping completionBlock){ if let unwrappedUrl = URL(string: strUrl){ URLSession.shared.dataTask(with: unwrappedUrl, completionHandler: { (data, response, error) in if data != nil{ let jsonDecoder = JSONDecoder() let userArray = try? jsonDecoder.decode([User].self, from: data!) if userArray != nil{ completionBlock(userArray!) }else{ let aArray = [User]() completionBlock(aArray) } }else{ let aArray = [User]() completionBlock(aArray) } }).resume() } } }
// // ViewController.swift // MVVM_Example // // Created by Rathaur on 02/07/20. // Copyright © 2020 AppCodeZip. All rights reserved. // import UIKit class ViewController: UIViewController{ @IBOutlet weak var tblView: UITableView! var viewModel = UserViewModel() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. viewModel.getDataFromAPIHandlerClass(url: EndPoint.strUrl) { (_) in DispatchQueue.main.async { [weak self] in self?.tblView.reloadData() } } } } extension ViewController : UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 90.0 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return viewModel.getNumberOfRowsInSection() } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell") cell?.textLabel?.text = viewModel.getCellData(index: indexPath.row) cell?.detailTextLabel?.text = viewModel.getDetailCellData(index: indexPath.row) return cell! } func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { if(indexPath.row % 2 == 0) { cell.backgroundColor = UIColor.red.withAlphaComponent(0.05) } else { cell.backgroundColor = UIColor.white } } }
0 Comments