问题描述
我正在尝试使用MVP从GitHub API获取信息。
通过在UISearchBar中输入的字符搜索GitHub用户。
结果,我能够将信息从模型传递给Presenter,但是Presenter的以下部分显示了一个错误。
self.view.reloadData(result) // Unexpectedly found nil while implicitly unwrapping an Optional value
我该如何解决这个问题?
模型
import Foundation
class usermodel {
//MARK: - Vars
var userData = [SearchResult.UserData]()
//MARK: - Fetch GitHubUser Data
func fetchUserData(text: String,completion: @escaping ([SearchResult.UserData]) -> Void) {
let urlString = "https://api.github.com/search/users?q=\(text.trimmingCharacters(in: .whitespaces))"
let encode = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
guard let url = URL(string: encode) else {
return
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request,completionHandler: { (data,response,error) in
if let data = data {
do {
let searchedUserData = try JSONDecoder().decode(SearchResult.self,from: data).items
self.userData = searchedUserData
dump(self.userData)
completion(self.userData)
} catch {
print(error.localizedDescription)
}
}
})
task.resume()
}
}
演示者
import Foundation
protocol Input {
func didTappedSearchButton(searchText: String)
}
protocol UserView: AnyObject {
func reloadData(_ users: [SearchResult.UserData])
}
final class SearchUserViewPresenter: Input {
//MARK: - Vars
var model = usermodel()
private weak var view: UserView!
//MARK: - Function
func didTappedSearchButton(searchText: String) {
print("Receive " + searchText)
model.fetchUserData(text: searchText,completion: { result in
print("Result",result)
self.view.reloadData(result) // Unexpectedly found nil while implicitly unwrapping an Optional value
})
}
}
视图
import UIKit
class SearchUserViewController: UIViewController {
//MARK: - Vars
private var presenter = SearchUserViewPresenter()
var userData = [SearchResult.UserData]()
var selectedUrl: String!
var userName: String!
//MARK: - IBOutlet
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var searchBar: UISearchBar!
//MARK: - View LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
// tableViewの設定
tableView.dataSource = self
tableView.delegate = self
tableView.tableFooterView = UIView(frame: .zero)
// tableViewのcellにxibを設定
let cellNib = UINib(nibName: "SearchUserTableViewCell",bundle: nil)
tableView.register(cellNib,forCellReuseIdentifier: "Cell")
// searchBarの設定
searchBar.delegate = self
searchBar.autocapitalizationType = .none
searchBar.keyboardType = .alphabet
navigationItem.title = "Search User"
}
}
//MARK: - taleView DataSource
extension SearchUserViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
return userData.count
}
func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell",for: indexPath) as! SearchUserTableViewCell
let userViewData = userData[indexPath.row]
cell.userNameLabel.text = userViewData.login
cell.avatarImageView.image = UIImage(url: userViewData.avatarUrl)
cell.userTypeLabel.text = userViewData.type
return cell
}
}
//MARK: - tableView Delegate
extension SearchUserViewController: UITableViewDelegate {
func tableView(_ table: UITableView,didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath,animated: true)
let userViewData = userData[indexPath.row]
selectedUrl = userViewData.url
userName = userViewData.login
performSegue(withIdentifier: "showUserDetail",sender: nil)
}
override func prepare(for segue: UIStoryboardSegue,sender: Any!) {
if segue.identifier == "showUserDetail" {
let userDetailVC: UserDetailViewController = segue.destination as! UserDetailViewController
userDetailVC.userUrl = selectedUrl!
userDetailVC.titleText = userName!
}
}
}
//MARK: - searchBar Delegate
extension SearchUserViewController: UISearchBarDelegate {
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchBar.setShowsCancelButton(true,animated: true)
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.endEditing(true)
guard let text = searchBar.text else {return}
presenter.didTappedSearchButton(searchText: text)
searchBar.setShowsCancelButton(false,animated: true)
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.endEditing(true)
searchBar.text = ""
searchBar.setShowsCancelButton(false,animated: true)
}
}
//MARK: - Protocol UserView
extension SearchUserViewController: UserView {
func reloadData(_ users: [SearchResult.UserData]) {
userData = users
print(users)
if self.userData == [] {
self.errorHUD()
} else {
self.tableView.reloadData()
self.tableView.scrollToRow(at: IndexPath(row: 0,section: 0),at: .top,animated: true)
self.hideProgress()
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)