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