I got some nil values are exist into API as found into console window . I marked the filed as option into model as well other view controller But still giving me same message . No exact matches in call to initializer
Here is my model .
import Foundation
// MARK: - Welcome
struct Coin: Codable {
let venues: [Venue]
}
// MARK: - Venue
struct Venue: Codable {
let id: Int?
let lat, lon: Double?
let category, name: String?
let createdOn: Int?
let geolocationDegrees: String
enum CodingKeys: String, CodingKey {
case id, lat, lon, category, name
case createdOn = "created_on"
case geolocationDegrees = "geolocation_degrees"
}
}
Here is the presenter class.
import Foundation
import UIKit
class VenuePresenter : VanueProtocol{
// creating instance of the class
private let view : VanueViewProtocol
private let networkManager: NetworkManager
private var vanues = [Venue]()
var rows: Int{
return vanues.count
}
// initilanize the class
init(view:VanueViewProtocol , networkmanager:NetworkManager = NetworkManager()){
self.view = view
self.networkManager = networkmanager
}
func getVanue(){
let url = "https://coinmap.org/api/v1/venues/"
networkManager.getCoins(from: url) { result in
switch result {
case.success(let respone):
self.vanues = respone.venues
DispatchQueue.main.async {
self.view.resfreshTableView()
}
case .failure(let error):
DispatchQueue.main.async {
self.view.displayError(error.localizedDescription)
//self.view.displayError(error.errorDescription ?? "")
print(error)
}
}
}
}
func getId(by row: Int) -> Int? {
return vanues[row].id
}
func getLat(by row: Int) -> Double? {
return vanues[row].lat
}
func getCreated(by row: Int) -> Int? {
return vanues[row].createdOn
}
func getLon(by row: Int) -> Double? {
return vanues[row].lon
}
}
Here is the view controller class.
import UIKit
class ViewController: UIViewController{
private var presenter : VenuePresenter!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
setUpUI()
presenter = VenuePresenter(view: self)
presenter.getVanue()
self.tableView.register(DisplayView.self, forCellReuseIdentifier: DisplayView.identifier)
}
private func setUpUI() {
tableView.dataSource = self
tableView.delegate = self
}
}
extension ViewController : VanueViewProtocol{
func resfreshTableView() {
tableView.reloadData()
}
func displayError(_ message: String) {
let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
let doneButton = UIAlertAction(title: "Done", style: .default, handler: nil)
alert.addAction(doneButton)
present(alert, animated: true, completion: nil)
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
presenter.rows
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: DisplayView.identifier, for: indexPath) as? DisplayView
else { return UITableViewCell() }
//tableView.register(UITableViewCell.self, forCellReuseIdentifier: "DisplayView1")
let row = indexPath.row
guard let id = presenter.getId(by: row) else { return UITableViewCell()}
guard let lat = presenter.getLat(by: row) else { return UITableViewCell () }
guard let lon = presenter.getLon(by: row) else { return UITableViewCell() }
guard let createdOn = presenter.getCreated(by: row) else { return UITableViewCell() }
cell.configureCell(id: id, lat: lat, lon: lon, createdOn: createdOn)
return cell
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
Here is the display view controller .
import UIKit
class DisplayView: UITableViewCell{
static let identifier = "DisplayView"
@IBOutlet weak var label1: UILabel!
@IBOutlet weak var label2: UILabel!
@IBOutlet weak var label3: UILabel!
@IBOutlet weak var label4: UILabel!
func configureCell(id: Int ,lat : Double , lon : Double , createdOn: Int){
label1.text = String(id)
label2.text = String(lat)
label3.text = String(lon)
label4.text = String(createdOn)
}
}
Here is the screenshot of the error message .
CodePudding user response:
have you tried using "(lat)" ?
label2.text = "\(lat)"
you also might want to unwrap the optionals since you are alsoi getting an error
label1.text = "\(id ?? "default")"
CodePudding user response:
You aren't registering your cell reuse identifier correctly if you want to use a nib file.
self.tableView.register(DisplayView.self, forCellReuseIdentifier: DisplayView.identifier)
will initialise an instance if your cell class when required, but the outlets will not be connected as there is no connection to your nib file. This causes the "unexpectedly nil" crash. The errors in subsequent lines aren't relevant.
You need to register your nib with the tableview using register(_ nib:UINib?, forCellReuseIdentifier: String)