0

I'm using a UITabBarController to create a contact list, but when I'm trying to save the array to load the data when I restart the app is giving me problems where the data isn't displayed. I'm using UserDefaults to save the data and the restore when the app is restarted.

In this code I sent data from a textfield to the array named list.

import UIKit

class NewContactoViewController: UIViewController {

@IBOutlet weak var input: UITextField!

@IBAction func add(_ sender: Any) {
    if (input.text != "") {

        list.append(input.text!)
        UserDefaults.standard.set(list, forKey: "SavedValue")
        input.text = ""
    }
}
}

In this code I'm printing the data in a table, and trying to save it with user defaults.

import UIKit

var list = [String]()

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if let x = UserDefaults.standard.object(forKey: "SavedValue") as? String {
        return (x.count)
    }
    return (0)
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
    if let x = UserDefaults.standard.dictionary(forKey: "SavedValue") as? String {
        cell.textLabel?.text = [x[indexPath.row]]
    }
    return(cell)
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == UITableViewCellEditingStyle.delete {
        list.remove(at: indexPath.row)
        myTableView.reloadData()
    }
}

override func viewDidAppear(_ animated: Bool) {
    myTableView.reloadData()
}

@IBOutlet weak var myTableView: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

}
}
Jay Patel
  • 2,642
  • 2
  • 18
  • 40
Edwin Lima
  • 15
  • 2
  • How you declare list array in NewContactoViewController? and explain more that how you communicate ViewController? – Jay Patel Nov 28 '17 at 05:17

1 Answers1

0

You are saving an array of strings but you are reading a single string (or even a dictionary) which obviously cannot work. There is a dedicated method stringArray(forKey to read a string array.

Apart from the issue never read from UserDefaults to populate the data source in the table view data source and delegate methods, do it in viewDidLoad or viewWillAppear for example

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if let savedArray = UserDefaults.standard.stringArray(forKey: "SavedValue") {
        list = savedArray
    }
    myTableView.reloadData()
}

Put the data source array in the view controller. A global variable as data source is very bad programming habit.

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var list = [String]()
    ...

In numberOfRowsInSection return the number of items in list and return is not a function, there are no parentheses

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

Same in cellForRow. Get the item from list and use reusable cells and again, return is not a function.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = list[indexPath.row]
    return cell
}

Note :

Consider that UserDefaults is the wrong place to share data between view controllers. Use segues, callbacks or protocol / delegate.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thanks it help me a lot, the reason why I declare the array as a global variable it was to access it from the other controller for the tab controller, didn't knew it was a bad habit. – Edwin Lima Nov 28 '17 at 15:43