I CAN'T SAVE through NSUserDefaults the values ​​collected by the checkmarker to be transferred to another controller in a specific table cell (CODE ALREADY CORRECTED) import UIKit

class Exersise: NSObject, NSCoding { var name: String var image: String var checked: Bool init(name: String, image: String, checked: Bool) { self.name = name self.image = image self.checked = checked } required init(coder aDecoder: NSCoder) { self.name = aDecoder.decodeObjectForKey("name") as! String self.image = aDecoder.decodeObjectForKey("image") as! String self.checked = aDecoder.decodeObjectForKey("checked") as! Bool } func encodeWithCoder(aCoder: NSCoder) { [aCoder.encodeObject(self.name, forKey: "name")] [aCoder.encodeObject(self.image, forKey: "image")] [aCoder.encodeObject(self.checked, forKey: "checked")] } } // Эта функция обязательно должна быть глобальной и требуется протоколом Equatable, без неё компилятор будет ругаться, что структура не соответствует протоколу. func ==(lhs: Exersise, rhs: Exersise) -> Bool { return lhs.name == rhs.name && lhs.image == rhs.image } var exersise = [Exersise]() // заменяем tuple на класс class AllExersiseTableViewController: UITableViewController { //создаем секции struct Objects { var sectionName: String! var sectionObjects: [Exersise]! } var objectsArray = [Objects]() override func viewDidLoad() { super.viewDidLoad() //Элементы секций objectsArray = [ Objects(sectionName: "Standing", sectionObjects: [ Exersise(name: "Приседания", image:"bb", checked: false), Exersise(name: "Отжимания", image:"bt", checked: false)]), Objects(sectionName: "Sitting", sectionObjects: [ Exersise(name: "БЕГ", image:"ru", checked: false), Exersise(name: "ПРЫЖКИ", image:"al", checked: false)]), Objects(sectionName: "Sitting", sectionObjects: [ Exersise(name: "БЕГ", image:"ru", checked: false), Exersise(name: "ПРЫЖКИ", image:"al", checked: false)])] } 

Selection from the list of necessary items by the checkmarker for saving and transferring

  //нажатие на ячейку override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { guard let cell = tableView.cellForRowAtIndexPath(indexPath) else { return } // убеждаемся, что ячейка правильная let object = objectsArray[indexPath.section].sectionObjects[indexPath.row] if object.checked { cell.accessoryType = .None object.checked = false if let index = exersise.indexOf(object) { // находим реальный индекс объекта в массиве exersise.removeAtIndex(index) // удаляем объект по правильному индексу } } else { cell.accessoryType = .Checkmark object.checked = true exersise.append(object) //добавляем в массив элементы ячейки } 

further in the alert we save the selected elements and create the name of the cell to which we will transmit the selected elements

  workout.append(self.nameWorkoutTextField.text!)//текст получаем из текстфилда, оно работает self.nameWorkoutTextField.text = "" NSUserDefaults.standardUserDefaults().setObject(workout, forKey: "workout")//создаем название ячейки let data: NSData = NSKeyedArchiver.archivedDataWithRootObject(exersise) NSUserDefaults.standardUserDefaults().setObject(data, forKey: "Exersise") NSUserDefaults.standardUserDefaults().synchronize() //сохраняем выбранные элементы 

Further, the controller in which the created cells are displayed with the elements selected from the list. In each new cell, selected items should be stored respectively for each specific one.

 var workout = [String]()//вынесен за класс контроллера override func viewDidLoad() { super.viewDidLoad() if NSUserDefaults.standardUserDefaults().objectForKey("workout") != nil { workout = NSUserDefaults.standardUserDefaults().objectForKey("workout") as! [String] }//читаем название ячейки if NSUserDefaults.standardUserDefaults().objectForKey("exersise") != nil { let newData: NSData = NSUserDefaults.standardUserDefaults().objectForKey("Exersise") as! NSData let newArr: Array = NSKeyedUnarchiver.unarchiveObjectWithData(newData) as! [Exersise] let newObject: Exersise = newArr[0] print(newObject.name) print(newObject.image)//читаем выбранные элементы для этой ячейки } 

Display the cell

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let myCell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) myCell.textLabel?.text = workout[indexPath.row] return myCell } 

The list of elements for this cell is not necessary to display, but when you click on this cell, we switch to another controller in which we will display the list of elements of this cell. I DO NOT UNDERSTAND THE MECHANISM HOW TO ASSIGN THE SELECTED ELEMENTS TO SPECIFICALLY CREATE A CELL FOR THEM, BECAUSE NOW WHEN CREATING MULTIPLE CELLS AND STEPPING IN THEM, THEY DISPOSE ONE OFTIMS.

  • How can this all be reduced to the part that needs help? you have a saved array is not readable from UserDefaults? - Max Mikheyenko
  • When saving the selected elements, the application crashes, I think that probably the saving is not correct. I can't correct it here yet - Artur Skachkov
  • And I don’t understand saving to a specific cell - Artur Skachkov
  • if I understand correctly, are you trying to save your Exersise class in NSUserDefaults? if so, then your class should have the encodeWithCoder and initWithCoder methods, which should encode and decode all the variables that need to be saved and loaded. In other words, explain to the system what is saving and loading for this type of object. stackoverflow.com/questions/2315948/… - Max Mikheyenko
  • corrected the answer. - Max Mikheyenko

1 answer 1

In the Exersise class, you need to write the following two methods (replace all objects with real objects from your class), and make sure that NSCoding is specified in Exersise

 class customObject: NSObject, NSCoding { var custom: String! var anotherCustom: Int! required init?(coder aDecoder: NSCoder) { self.custom = aDecoder.decodeObjectForKey("custom") as! String self.anotherCustom = aDecoder.decodeObjectForKey("anotherCustom") as! Int } func encodeWithCoder(aCoder: NSCoder) { [aCoder .encodeObject(self.custom, forKey: "custom")] [aCoder .encodeObject(self.anotherCustom, forKey: "anotherCustom")] } } 

Preservation

 var data:NSData = NSKeyedArchiver.archivedDataWithRootObject(self.customObject) NSUserDefaults.standardUserDefaults().setObject(data, forKey: "customObject") NSUserDefaults.standardUserDefaults().synchronize() 

Loading

 let newData:NSData = NSUserDefaults.standardUserDefaults().objectForKey("customObject") as! NSData let newObj:customObject = NSKeyedUnarchiver.unarchiveObjectWithData(newData) as! customObject 

If you have an array of such objects, in general, nothing changes:

Preservation

 var arr: [customObject]! //populate array var data:NSData = NSKeyedArchiver.archivedDataWithRootObject(self.arr) NSUserDefaults.standardUserDefaults().setObject(data, forKey: "customObject") NSUserDefaults.standardUserDefaults().synchronize() 

Loading

 let newData:NSData = NSUserDefaults.standardUserDefaults().objectForKey("customObject") as! NSData let newArr:Array = NSKeyedUnarchiver.unarchiveObjectWithData(newData) as! [customObject] var newObject:customObject = newArr[0] //и так далее 
  • Comments are not intended for extended discussion; conversation moved to chat . - PashaPash
  • @PashaPash a tick then why was to clean - Max Mikheyenko
  • Tick ​​moderators can not remove. She shot the author of the question. - PashaPash
  • Moreover , they scared the person so much that he removed the tick from the good answer - Max Mikheyenko
  • I have nothing to do with it, just blew comments into the chat :) - PashaPash