Last active
June 9, 2020 21:09
-
-
Save DhavalDobariya86/05c8551c3e8d8ab90a58be1cdc32630b to your computer and use it in GitHub Desktop.
MVVM-C ViewModel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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