NSUserDefaults ne fonctionne pas avec UITableView dans Swift

Je suis relativement nouveau à Swift et je fais une application de journal de devoirs de base. Ce que j'ai jusqu'ici est un UITableView incorporé dans un controller de navigation qui est incorporé dans un controller de barre d'tabs. J'ai réussi à mettre en œuvre un pull pour actualiser, append des données dans un UIAlertView et peupler la table avec ces données après l'actualisation. J'ai besoin de données persistantes pour cette application et j'ai entendu que NSUserDefaults est le meilleur moyen de le faire, mais cela ne fonctionne pas pour moi. Je peux voir qu'il s'ajoute aux NSUserDefaults, mais il ne semble pas réapparaître dans UITableView après que je ferme et rouvre l'application. Aucune suggestion? Mon code est ci-dessous. En outre, pour mettre ces données en ligne, existe-t-il un moyen d'utiliser Google Sheets comme database en ligne pour mon application?

import UIKit var classsData = [Ssortingng]() var teachersData = [Ssortingng]() let defaults = NSUserDefaults.standardUserDefaults() var tableData1 = defaults.valueForKey("classsData") as! NSArray var tableData2 = defaults.valueForKey("teachersData") as! NSArray class ClassesList: UIViewController, UITableViewDelegate, UITableViewDataSource, UIPopoverPresentationControllerDelegate { lazy var refreshControl: UIRefreshControl = { let refreshControl = UIRefreshControl() refreshControl.addTarget(self, action: "handleRefresh:", forControlEvents: UIControlEvents.ValueChanged) return refreshControl }() @IBOutlet weak var tableView: UITableView! @IBAction func addClass(sender: AnyObject) { var subjectTextField: UITextField? var teacherTextField: UITextField? let alertController = UIAlertController(title: "Add Class", message: "Please input the name of the subject and the teaceher", preferredStyle: .Alert) let done = UIAlertAction(title: "Done", style: .Default, handler: { (action) -> Void in classsData.append(subjectTextField!.text!) teachersData.append(teacherTextField!.text!) print(classsData) print(teachersData) }) let cancel = UIAlertAction(title: "Cancel", style: .Cancel) { (action) -> Void in } alertController.addAction(done) alertController.addAction(cancel) alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in // Enter the textfiled customization code here. subjectTextField = textField subjectTextField?.placeholder = "Subject" } alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in // Enter the textfiled customization code here. teacherTextField = textField teacherTextField?.placeholder = "Teacher" } presentViewController(alertController, animated: true, completion: nil) } override func viewDidLoad() { super.viewDidLoad() self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "classCell") self.tableView.addSubview(self.refreshControl) // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func handleRefresh(refreshControl: UIRefreshControl) { defaults.setValue(classsData, forKey: "classsData") defaults.setValue(teachersData, forKey: "teachersData") print(tableData1) defaults.synchronize() self.tableView.reloadData() refreshControl.endRefreshing() } func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return classsData.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("classCell")! as UITableViewCell cell.textLabel?.text = (tableData1[indexPath.row] as? Ssortingng)! + " , " + (tableData2[indexPath.row] as? Ssortingng)! return cell } } 

Au démarrage, vous utilisez tableData1 & tableData2 pour stocker les informations par défaut, mais classsData et teachersData sont initialisées pour être vides. Lorsque l'application démarre, elle appelle numberOfRowsInSection et renvoie classsData.count qui est égal à zéro. L'autre problème que vous avez, c'est que votre application va se bloquer la toute première fois qu'elle est exécutée parce que vous l'initialisez avec des données NSUserDefaults qui sont vides. Réinitialisez le simulateur iOS, puis exécutez votre application et elle va planter. Vous devez vérifier et gérer datatables vides de NSUserDefaults qui est couvert ici: comment save et lire tableau de tableau dans NSUserdefaults dans swift?

Je suggère ce qui suit: 1) supprimer tableData1 & tableData1 et replace par classsData et teachersData partout dans l'application. 2) Créez une nouvelle fonction appelée loadUserDefaults () appelée dans viewDidLoad qui charge datatables de NSUserDefaults lors de la vérification des données NSUserDefaults vides. 3) Dans handleRefresh (), sauvegardez simplement datatables, rechargez la vue de table et terminez l'actualisation. Avec ces suggestions, le code de travail est ci-dessous.

 import UIKit var classsData = [Ssortingng]() var teachersData = [Ssortingng]() let defaults = NSUserDefaults.standardUserDefaults() class ClassesList: UIViewController, UITableViewDelegate, UITableViewDataSource, UIPopoverPresentationControllerDelegate { lazy var refreshControl: UIRefreshControl = { let refreshControl = UIRefreshControl() refreshControl.addTarget(self, action: "handleRefresh:", forControlEvents: UIControlEvents.ValueChanged) return refreshControl }() @IBOutlet weak var tableView: UITableView! @IBAction func addClass(sender: AnyObject) { var subjectTextField: UITextField? var teacherTextField: UITextField? let alertController = UIAlertController(title: "Add Class", message: "Please input the name of the subject and the teaceher", preferredStyle: .Alert) let done = UIAlertAction(title: "Done", style: .Default, handler: { (action) -> Void in classsData.append(subjectTextField!.text!) teachersData.append(teacherTextField!.text!) }) let cancel = UIAlertAction(title: "Cancel", style: .Cancel) { (action) -> Void in } alertController.addAction(done) alertController.addAction(cancel) alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in // Enter the textfiled customization code here. subjectTextField = textField subjectTextField?.placeholder = "Subject" } alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in // Enter the textfiled customization code here. teacherTextField = textField teacherTextField?.placeholder = "Teacher" } presentViewController(alertController, animated: true, completion: nil) } override func viewDidLoad() { super.viewDidLoad() self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "classCell") self.tableView.addSubview(self.refreshControl) loadUserDefaults() } func handleRefresh(refreshControl: UIRefreshControl) { defaults.setValue(classsData, forKey: "classsData") defaults.setValue(teachersData, forKey: "teachersData") defaults.synchronize() self.tableView.reloadData() refreshControl.endRefreshing() } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return classsData.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("classCell")! as UITableViewCell cell.textLabel?.text = (classsData[indexPath.row] as? Ssortingng)! + " , " + (teachersData[indexPath.row] as? Ssortingng)! return cell } func loadUserDefaults() { if let tempClassArray = defaults.valueForKey("classsData") { classsData = tempClassArray as! [Ssortingng] } if let tempTeacherArray = defaults.valueForKey("classsData") { teachersData = tempTeacherArray as! [Ssortingng] } } }