Skip to content

Instantly share code, notes, and snippets.

@seyhunak
Last active November 9, 2023 08:02
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save seyhunak/ac6398f682b7a150502d885fa478d678 to your computer and use it in GitHub Desktop.
Save seyhunak/ac6398f682b7a150502d885fa478d678 to your computer and use it in GitHub Desktop.
Swift 5 - MVVM - ViewController, ViewModel, Model, Datasource, Webservice
import Foundation
class APIService : NSObject {
private let sourcesURL = URL(string: "http://dummy.restapiexample.com/api/v1/employees")!
func apiToGetEmployeeData(completion : @escaping (Employees) -> ()){
URLSession.shared.dataTask(with: sourcesURL) { (data, urlResponse, error) in
if let data = data {
let jsonDecoder = JSONDecoder()
let empData = try! jsonDecoder.decode(Employees.self, from: data)
completion(empData)
}
}.resume()
}
}
import Foundation
struct Employees: Decodable {
let status: String
let data: [EmployeeData]
}
struct EmployeeData: Decodable {
let id, employeeName, employeeSalary, employeeAge: String
let profileImage: String
enum CodingKeys: String, CodingKey {
case id
case employeeName = "employee_name"
case employeeSalary = "employee_salary"
case employeeAge = "employee_age"
case profileImage = "profile_image"
}
}
import Foundation
class EmployeesViewModel : NSObject {
private var apiService : APIService!
private(set) var empData : Employees! {
didSet {
self.bindEmployeeViewModelToController()
}
}
var bindEmployeeViewModelToController : (() -> ()) = {}
override init() {
super.init()
self.apiService = APIService()
callFuncToGetEmpData()
}
func callFuncToGetEmpData() {
self.apiService.apiToGetEmployeeData { (empData) in
self.empData = empData
}
}
}
import UIKit
class EmployeeTableViewCell: UITableViewCell {
@IBOutlet weak var employeeIdLabel: UILabel!
@IBOutlet weak var employeeNameLabel: UILabel!
var employee : EmployeeData? {
didSet {
employeeIdLabel.text = employee?.id
employeeNameLabel.text = employee?.employeeName
}
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
import UIKit
class EmployeeTableViewController: UIViewController {
@IBOutlet weak var employeeTableView: UITableView!
private var employeeViewModel : EmployeesViewModel!
private var dataSource : EmployeeTableViewDataSource<EmployeeTableViewCell,EmployeeData>!
override func viewDidLoad() {
super.viewDidLoad()
callToViewModelForUIUpdate()
}
func callToViewModelForUIUpdate(){
self.employeeViewModel = EmployeesViewModel()
self.employeeViewModel.bindEmployeeViewModelToController = {
self.updateDataSource()
}
}
func updateDataSource(){
self.dataSource = EmployeeTableViewDataSource(cellIdentifier: "EmployeeTableViewCell", items: self.employeeViewModel.empData.data, configureCell: { (cell, evm) in
cell.employeeIdLabel.text = evm.id
cell.employeeNameLabel.text = evm.employeeName
})
DispatchQueue.main.async {
self.employeeTableView.dataSource = self.dataSource
self.employeeTableView.reloadData()
}
}
}
import Foundation
import UIKit
class EmployeeTableViewDataSource<CELL : UITableViewCell,T> : NSObject, UITableViewDataSource {
private var cellIdentifier : String!
private var items : [T]!
var configureCell : (CELL, T) -> () = {_,_ in }
init(cellIdentifier : String, items : [T], configureCell : @escaping (CELL, T) -> ()) {
self.cellIdentifier = cellIdentifier
self.items = items
self.configureCell = configureCell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! CELL
let item = self.items[indexPath.row]
self.configureCell(cell, item)
return cell
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment