1

I want to send data from the tableview to the tableview of another ViewController. However, when pass the data, the data is converted to optional type.

So the SQL statement to be executed in another ViewController is not executed. An optional error occurred in ViewDidLoad.

I have also used the override prepare function, but the result is the same. I can't understand why this is happening.

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let itemCd = self.itemList[indexPath.row].itemCd
    let itemName = self.itemList[indexPath.row].itemName

    print(self.itemList[indexPath.row].itemCd)

    let infoVC = self.storyboard?.instantiateViewController(withIdentifier: "HIST_RVC")
    if let _infoVC = infoVC as? HistviewController {

        _infoVC.itemCd = Int(itemCd)
        _infoVC.itemName = String(itemName)

        print(_infoVC.itemCd)
        self.performSegue(withIdentifier: "moveHist", sender: self)
    }

When I print, I get the following result,

first : 1,
second : Optional(1)

other viewController:

class HistviewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

var itemCd: Int!
var itemName: String!
// SQLite DB
var infomationDAO = infoDAO()
var infoList: [InfoVO]!

override func viewDidLoad() {

    self.infoList = self.infomationDAO.find(itemCd: self.itemCd)
    self.tableview.reloadData()
}

sql find() function:

func find(itemCd: Int = 0) -> [InfoVO] {

    var infoList = [InfoVO]()

    do {
        // define condition
        let condition = itemCd == 0 ? "": "WHERE a.item_cd = \(itemCd)"

        let sql = """
        select a.info_cd, a.info_name, b.item_name
        from info_table a
        join item_table b
        on a.info_name = b.item_name
        \(condition)
        order by a.item_cd ASC
        """

        let rs = try self.fmdb.executeQuery(sql, values: nil)

        while rs.next() {
        ...}
Henri Normak
  • 4,695
  • 2
  • 23
  • 33
dinggu
  • 111
  • 7

2 Answers2

1

As per your code your performing segue so you need to implement func prepare(for segue: UIStoryboardSegue, sender: Any?) in your controller and pass the value.

Code:

 var selectedIndex = 0
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let controller = segue.destination as? HistviewController {
                let itemCd = self.itemList[selectedIndex].itemCd
                let itemName = self.itemList[selectedIndex].itemName
                controller.itemcd = Int(itemcd)
                controller.itemName = String(itemName)
            }
        }

        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            self.selectedIndex = indexPath.row
        }
iOS_Maccus
  • 377
  • 1
  • 11
0
  1. In HistviewController declare itemCd and itemName as non-optional. There are only a very few cases where it's useful to declare primitive types like String and Int as optional.

    var itemCd = 0
    var itemName = ""
    
  2. The init?(String) initializer return an optional because "abc" cannot be represented by an Int. Use the nil-coalescing operator to pass 0 if the initializer fails:

    _infoVC.itemCd = Int(itemCd) ?? 0
    

Note: In Swift avoid variable names with starting underscore character. That's very objective-c-ish. Write

if let infoVC = self.storyboard?.instantiateViewController(withIdentifier: "HIST_RVC") as? HistviewController {
vadian
  • 274,689
  • 30
  • 353
  • 361