Skip to content

Instantly share code, notes, and snippets.

@DhavalDobariya86
Last active June 9, 2020 21:09
Show Gist options
  • Save DhavalDobariya86/05c8551c3e8d8ab90a58be1cdc32630b to your computer and use it in GitHub Desktop.
Save DhavalDobariya86/05c8551c3e8d8ab90a58be1cdc32630b to your computer and use it in GitHub Desktop.
MVVM-C ViewModel
import Foundation
private struct CountryListEndpoint: EndpointReprsentable {
var httpMethod: HTTPMethod { .get }
var urlPath: URLPath { .name }
let pathComponent: String?
}
protocol CountryListViewModelLoadingErrorDelegate: class {
func didFailLoading(error: Error)
}
class CountryListViewModel: ViewModel, Searchable, CountryListDatasource {
private enum Constants {
static let title = "Countries"
static let loadingMessage = "Loading countries..."
}
var screenTitle: String { Constants.title }
var didUpdate: (() -> Void)?
var didChangeState: ((_ isLoading: Bool, _ loadingMessage: String?) -> Void)?
weak var loadingErrorDelegate: CountryListViewModelLoadingErrorDelegate?
private let requestManager: RequestManager
// MARK: - ViewModel
private var countries = [Country]() {
didSet {
didUpdate?()
}
}
private(set) var isLoading: Bool = false {
didSet {
didChangeState?(isLoading, isLoading ? Constants.loadingMessage : nil)
}
}
// MARK: - Object lifecycle
init(requestManager: RequestManager) {
self.requestManager = requestManager
}
// MARK: - Searchable
func searchFor(keyword: String) {
let endpoint = CountryListEndpoint(pathComponent: keyword)
isLoading = true
requestManager.performRequest(endPoint: endpoint, completionQueue: .main, parser: JSONParser()) {
[weak self] (result: Result<[Country], Error>) in
guard let self = self else { return }
self.isLoading = false
switch result {
case .success(let countries):
self.countries = countries
case .failure(let error):
self.loadingErrorDelegate?.didFailLoading(error: error)
}
}
}
}
// MARK: - CountryListDatasource
extension CountryListViewModel {
var numberOfSections: Int { 1 }
func numberOfRows(in section: Int) -> Int { countries.count }
func country(at indexPath: IndexPath) -> Country? { countries[indexPath.row] }
func itemForRow(at indexPath: IndexPath) -> CountryListItemRepresentable { countries[indexPath.row] }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment