I'm working on MVVM architecture in Swift with UITableView
. For this, I have created sample table view.
Can any one please suggest whether I am going correct or any other improvements need to do?
The following are the classes for this architecture.
ViewController - Contains UITableView
and its delegate
and datasource
methods.
class ViewController: UIViewController {
let PRODUCT_CELL_IDENTIFIER = "ProductCellIdentifier"
@IBOutlet weak var productTableView: UITableView!
var productViewModel: ProductViewModel = ProductViewModel()
}
//UITableView Delegate Methods
extension ViewController {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return productViewModel.numberOfRowsInSection()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: PRODUCT_CELL_IDENTIFIER) as! ProductTableViewCell
let product = productViewModel.productsArray[indexPath.row]
cell.productName.text = product.name
cell.productQuantity.text = "\(product.quantity)"
return cell
}
}
ProductViewModel: - This is ViewModel class.
class ProductViewModel: NSObject {
var productsArray = Array<Product>()
override init() {
let product1 = Product(name: "Prodcut1", image_url: "", quantity: 2)
let product2 = Product(name: "Prodcut2", image_url: "", quantity: 3)
productsArray.append(product1)
productsArray.append(product2)
}
func numberOfRowsInSection() -> Int {
return productsArray.count
}
}
Product - This is the model class
class Product: NSObject {
var name: String
var image_url: String
var quantity: Int
init(name: String, image_url: String, quantity: Int) {
self.name = name
self.image_url = image_url
self.quantity = quantity
}
}
ProductTableViewCell - This is UITableViewCell class
class ProductTableViewCell: UITableViewCell {
@IBOutlet weak var productQuantity: UILabel!
@IBOutlet weak var productName: UILabel!
@IBOutlet weak var productImageView: UIImageView!
}
KEY DIFFERENCE In MVC, controller is the entry point to the Application, while in MVVM, the view is the entry point to the Application. MVC Model component can be tested separately from the user, while MVVM is easy for separate unit testing, and code is event-driven.
MVVM (Model View ViewModel) is a design pattern, which has been widely used as more event-driven apps have started emerging. A few years back, if anyone built a product, it has probably been built using MVC (Model View Controller). In recent times, the MVC architecture has lost its place as the default design pattern.
The difference between the MVC and MVVM is View and controller are responsible for calculating the value and assigning the value so the load is more on View and Controller where in MVVM View and Controller are only responsible for assigning the value not calculating the value.
You are doing good job, but you can even improve you product model with adding following function to get array of direct models. It is very useful when you have create array from web Api response.
class Product : NSObject
{
var imgUrl : String!
var name : String!
var quantity : Int!
init(dictionary: [String:Any])
{
imgUrl = dictionary["img_url"] as? String
name = dictionary["name"] as? String
quantity = dictionary["quantity"] as? Int
}
init(name: String, image_url: String, quantity: Int)
{
self.name = name
self.imgUrl = image_url
self.quantity = quantity
}
public class func modelsFromArray(array:[[String:Any]]) -> [Product]
{
var models:[Product] = []
for item in array
{
models.append(Product.init(dictionary:item))
}
return models
}
}
With Usage Like
let product1 = Product(name: "Prodcut1", image_url: "", quantity: 2) //Normal Case
let productList:[[String:Any]] =
[
["name":"Jaydeep","img_url":"xyz","quantity":1],
["name":"Jaydeep","img_url":"xyz","quantity":2],
["name":"Jaydeep","img_url":"xyz","quantity":3],
["name":"Jaydeep","img_url":"xyz","quantity":4],
["name":"Jaydeep","img_url":"xyz","quantity":5],
["name":"Jaydeep","img_url":"xyz","quantity":6]
]
//Assign Direct Dictionary to Get Array Of Models
/* Very useful when productList is dictionary from server response*/
let productArray:[Product] = Product.modelsFromArray(array: productList)
And Also your Cell Class is Improved By
class ProductTableViewCell: UITableViewCell {
@IBOutlet weak var productQuantity: UILabel!
@IBOutlet weak var productName: UILabel!
@IBOutlet weak var productImageView: UIImageView!
func setProductData(product:Product)
{
self.productName.text = product.name
self.productQuantity.text = "\(product.quantity)"
}
}
Usage:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: PRODUCT_CELL_IDENTIFIER) as! ProductTableViewCell
let product = productViewModel.productsArray[indexPath.row]
cell.setProductData(product:product)
return cell
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With