2

I am new to swift and what I am trying to do is return the specified columns in my table to display in a separate viewcontroller. I have defined a function using SQLite.swift which returns them in an array, just like I want them to be. (It works when called in the same viewcontroller)

func returncolumns() -> Array<String> {
    print("RETURNING")
    var namearray = [String]()
    do {
        for wardrobe in try wardrobedb.prepare(wardrobe.select(name)) {
            namearray.append(wardrobe[name])
        }
    } catch {
        print("This no worko \(error)")
    }
    return namearray
}

But when I call the function from another viewcontroller, I get a fatal error due to it trying to unwrap a nil value.

var clothes = ViewController().returncolumns()

What I gather is that since I am calling the function from the viewcontroller without the table, it is not able to get the information that it needs.

Here is the database in the first viewcontroller

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

var wardrobedb: Connection!

let wardrobe = Table("wardrobe")

let id = Expression<Int64>("id")
let name = Expression<String>("name")
let type = Expression<String>("type")
let color = Expression<String>("color")
let style = Expression<String>("style")
let weight = Expression<String>("weight")
let pattern = Expression<String>("pattern")

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

    do {
        let documentDirectory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        let fileUrl = documentDirectory.appendingPathComponent("wardrobe").appendingPathExtension("sqlite3")
        let wardrobedb = try Connection(fileUrl.path)
     //   let wardrobedb = try remove(fileUrl.path)
        self.wardrobedb = wardrobedb
    } catch {
        print(error)
    }
}

So should I try to combine the view controllers so that its all accessible? or move the wardrobe instantiation to another class? or is there a nice simple addition I can make to the function call which will allow for the table to be accessed.

Thank you!

Second ViewController:

import UIKit

class WardrobeTableViewController: UITableViewController {

var clothes = [String]()

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return clothes.count
}

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "Section \(section)"
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "LabelCell", for: indexPath)

    let clothesname = clothes[indexPath.row]
    cell.textLabel?.text = clothes[indexPath.row]
    cell.detailTextLabel?.text = "Very cool!"
//    cell.imageView?.image = UIImage(named: clothesname)

    return cell
}
}

Here is first viewcontroller calls

func returncolumns() -> Array<String> {
    print("RETURNING")
    var namearray = [String]()
    do {
        for wardrobe in try wardrobedb.prepare(wardrobe.select(name)) {
            namearray.append(wardrobe[name])
        }
    } catch {
        print("This no worko \(error)")
    }
    return namearray
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "wardrobemove" {
      //  if let destinationVC = segue.destination as? WardrobeTableViewController {
            WardrobeTableViewController().clothes = returncolumns()
      ///  }
    }
}

So here I am identifying "wardrobemove" as the segue which moves into a navigation controller. I commented out the if statement because in this instance the destination viewcontroller is the navigation controller not the WardrobeTableViewController where the clothes array is being stored. When I run the debugger, I see it passing the information and the clothes array being assigned. but it still disappears before that.

Between the Navigation controller and the WardrobeTableViewController there is a Table view controller which has a few cells and when the first one is selected, it opens the WardrobeTableViewController.

This is a bit of a mess, I have followed two guides and I think the second one bringing in the navigation controller has messed things up a bit.

1 Answer 1

2

EDIT 2: you were not setting the clothes property of the instance of the class the segue is performed (but you were setting a new instance). Change like this:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    //check if the performed segue has "wardrobemove" id
    if segue.identifier == "wardrobemove" {
        //check if the destination is kind of WardrobeTableViewController
        if let destinationVC = segue.destination as? WardrobeTableViewController {
            //if it is so, then set its property clothes
            destinationVC.clothes = returncolumns()
      }
   }
}

EDIT

In your second vc, you want to reload your tableView every time you set the array of clothes:

var clothes = [String]() {
    didSet {
        self.tableView.reloadData()
    }
}

Old answer

var clothes = ViewController().returncolumns()

You have everything in your FirstVC and you want to set clothes in the SecondVC based on the value returned by the method returncolumns()

If it is so, you might want to perform a segue between FirstVC and SecondVC, and implement prepareForSegue to set clothes. Something like:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "segueIdentifier" {
        if let destinationVC = segue.destination as? SecondViewController {
            destinationVC.clothes = returncolumns()
        }
    }
}
Sign up to request clarification or add additional context in comments.

10 Comments

Hi, so I am close on this I think. I see in the debugger that it is assigning the correct values to the clothes array in the second view controller. The problem is that once I leave the first controller and go to the second, the array is now empty. I don't know why it empties
I added it. It is pretty simple. I was reading it could have something to do with the navigation controller causing previous values to de-allocate? But am not too sure on that
see my edit, if everything was setting the right way, the only thing you missed is to reload your table once you set the array
The second setting of the clothes var is showing an invalid redeclaration. If I comment out that line, I am still seeing an empty array once the second view controller is reached
Yes it was part of the old answer. If you share the code about how you perform the segue and prepare, maybe we can figure it out
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.