Narheru
Narheru

Reputation: 45

Dealing with nIl? in UITableViewCell

Ok, after solving the problem with "the self" now I'm struggling to understand why I cannot unwrap the results from my MysqlDB. The app connects, retrieve datas and then it might show them. The problem is that it cannot unwrapp. Here the code

ViewController.swift

import UIKit
 class ViewController: UIViewController, UITableViewDataSource,     UITableViewDelegate, HomeModelProtocol {

//downloadItems
func itemsDownloaded(items: NSArray) {
    feedItems = items
    self.listTable.reloadData()
}

//link tV
@IBOutlet weak var listTable: UITableView!
//Proprietà
var feedItems: NSArray = NSArray()
var selectList : ListModel = ListModel()



//tableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return feedItems.count
}

//viewDidLoad
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    //set delegates and initialize a homeModel
    self.listTable.delegate = self
    self.listTable.dataSource = self

    let homeModel = HomeModel ()
    homeModel.delegate = self
    homeModel.downloadItems()
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->UITableViewCell {
    let cellIdentifier : String = "BasicCell"
    let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!

    //recupero food
    let item : ListModel = feedItems[indexPath.row] as! ListModel

    //reference alla label
    myCell.textLabel!.text = item.description

    return myCell
}}

ListModel.swift

import Foundation
class ListModel : NSObject {

//proprietà
var name: String?
var percentage: Int?
var other: String?
var id: Int?


override init(){
}

init(name: String, percentage: Int, other: String, id: Int){
    self.name = name
    self.percentage = percentage
    self.other = other
    self.id = id
}

//stampa oggetti
override var description: String{
    return "Name: \(name), Percentuale: \(String(describing: percentage)), Altro: \(other)"
}}

HomeModel.swift

import Foundation

protocol HomeModelProtocol: class {
    func itemsDownloaded(items: NSArray)
} 

class HomeModel: NSObject, URLSessionDataDelegate{
//proprietà
weak var delegate: HomeModelProtocol!
var data = Data()
let urlPath: String = "http://www.sake-house.net/webServices.php"

func downloadItems(){
    let url : URL = URL(string: urlPath)!
    let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
    let task = defaultSession.dataTask(with: url) {(data, response, error) in
        if error != nil{
            print("downloasd fallito")
        }else{
            print("Dati scaricati")
            parseJSON(data!)
        }
    }
    task.resume()
}} 
func parseJSON(_ data:Data){
var jsonResult = NSArray()

do{
    jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as! NSArray
} catch let error as NSError{
    print (error)
}

var jsonElement = NSDictionary()
let listFoods = NSMutableArray()

for i in 0..<jsonResult.count {
    jsonElement = jsonResult[i] as! NSDictionary

    let listF = ListModel()

    if let name = jsonElement["Name"] as? String, let percentage = jsonElement["Percentage"] as? Int, let other = jsonElement["other"] as? String, let id = jsonElement["id"] as? Int{
        listF.name = name
        listF.percentage = percentage
        listF.other = other
        listF.id = id
    }
    listFoods.add(listF)

    //check listFoods
    DispatchQueue.main.async(execute: { () -> Void in self.delegate.itemsDownload(items: listFoods)}) <--------HERE

}}//fine func parseJSON

The problem is on this row

let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!

"Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value"

In ViewController.swift. If I delete this line it works and show me Name: nil.

Upvotes: 0

Views: 784

Answers (2)

Narheru
Narheru

Reputation: 45

So, I have tried as Sh_Khan said. I think I'm missing something or I have done it wrong at all. Inside Viecontroller.swift

class CellName:UITableViewCell {

}
@IBOutlet weak var listTable: UITableView!

and then

tableView.register(CellName.self, forCellReuseIdentifier:cellIdentifier)
let myCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! CellName

Now I can see something but as result I see "nil"

Upvotes: 0

Shehata Gamal
Shehata Gamal

Reputation: 100503

This line crashes

 let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!

as you need to register the cell for that tableView , you need to create a custom cell then use

let myCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! CellName

Register

tableView.register(CellName.self, forCellReuseIdentifier:cellIdentifier)

// or for xib

tableView.register(UINib(nibName: "xibname", bundle: nil), forCellReuseIdentifier: cellIdentifier)

class CellName:UITableViewCell {

   // outlets here 

}

Upvotes: 1

Related Questions