[英]Reload TableView when API completes w/ MVVM
我正在使用Swift 4開發一個應用程序。我正在以編程方式構建我的應用程序 -沒有情節提要。
我有一個看起來像這樣的ViewController
class SearchController: UITableViewController {
private let cellID = "cellID"
fileprivate let searchController = UISearchController(searchResultsController: nil)
fileprivate let viewModel = SearchViewModel(client: DiscogClient())
override func viewDidLoad() {
super.viewDidLoad()
setupSearchBar()
setupTableView()
}
fileprivate func setupSearchBar() -> Void {
navigationItem.hidesSearchBarWhenScrolling = false
navigationItem.searchController = searchController
searchController.searchBar.delegate = self
}
fileprivate func setupTableView() -> Void {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellID)
tableView.tableFooterView = UIView()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel.cellViewModels.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath)
return cell
}
}
extension SearchController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
viewModel.search(term: searchText)
}
}
我有一個看起來像這樣的ViewModel
import Foundation
import UIKit
class SearchViewModel {
var cellViewModels: [Result] = []
private let client: APIClient
var results: SearchResults? {
didSet {
for result in (results?.results)! {
cellViewModels.append(result)
}
}
}
var isLoading: Bool = false {
didSet {
showLoading?()
}
}
var showLoading: (() -> Void)?
var reloadData: (() -> Void)?
var showError: ((Error) -> Void)?
init(client: APIClient) {
self.client = client
}
func search(term: String) {
if let client = client as? DiscogClient {
let endpoint = DiscogsEndpoint.search(term: term, searchType: .release)
client.fetch(with: endpoint) { (either) in
switch either {
case .success(let results):
self.results = results
case .error(let error):
self.showError?(error)
}
}
}
}
}
當我在var results: SearchResults?
上檢查didSet
時var results: SearchResults?
我可以看到該值是通過我的APIClient
設置的。
我要做的就是指示ViewController表在設置該值后重新加載其數據。
我不確定如何實現這一目標? 我以為我可以在didSet
上使用didSet
並擴展到ViewController上的方法。 這行不通,或者我不知道如何執行此操作。
我希望現在看到行數通過SearchController中的viewModel.cellViewModels.count
更新
您可以修改search
以接受完成阻止
func search(term: String, @escaping completion :() -> ()) {
if let client = client as? DiscogClient {
let endpoint = DiscogsEndpoint.search(term: term, searchType: .release)
client.fetch(with: endpoint) { (either) in
switch either {
case .success(let results):
self.results = results
completion()
case .error(let error):
self.showError?(error)
completion()
}
}
}
}
最后,您可以重新加載tableView
self.search(term: "abcd") {
self.tableView.reloadData()
}
人們可能經常會要求您implement protocols
並在ViewModel和View之間建立通信。 但是,使用塊還是協議始終是設計實現的詳細信息:)
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.