Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios API完成时重新加载TableView w/MVVM_Ios_Swift_Mvvm - Fatal编程技术网

Ios API完成时重新加载TableView w/MVVM

Ios API完成时重新加载TableView w/MVVM,ios,swift,mvvm,Ios,Swift,Mvvm,我正在Swift 4中开发一个应用程序。我正在以编程方式构建我的应用程序——没有故事板 我有一个像这样的ViewController class SearchController: UITableViewController { private let cellID = "cellID" fileprivate let searchController = UISearchController(searchResultsController: nil) filepri

我正在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)
    }

}
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)
                }

            }
        }
    }
}
我有一个像这样的视图模型

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)
    }

}
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
时,我可以看到该值是通过我的
APIClient
设置的

我要做的是指示ViewController表在设置该值后重新加载其数据

但我不确定如何实现这一点?我想我可以在cellViewModels上使用
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()
    }
人们可能经常要求您
实现协议
,并在ViewModel和View之间建立通信。但是否使用块或协议始终是一个设计实现细节:)


希望这有帮助

您可以修改
搜索
以接受完成块

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()
    }
人们可能经常要求您
实现协议
,并在ViewModel和View之间建立通信。但是否使用块或协议始终是一个设计实现细节:)


希望这有帮助

当然可以!非常感谢你,工作得很顺利charm@petepete:很高兴我能帮上忙:)当然是的,很高兴为您服务!非常感谢你,工作得很顺利charm@petepete:我很高兴能帮上忙:)编码愉快