Swift 3.0:在 TableView 的 UserDefaults 中存储数组

Posted

技术标签:

【中文标题】Swift 3.0:在 TableView 的 UserDefaults 中存储数组【英文标题】:Swift 3.0: Store array in UserDefaults for tableView 【发布时间】:2016-09-25 16:44:51 【问题描述】:

我正在尝试在 UserDefaults 中存储一个数组,但没有找到解决方案。我有一个structfunc 设置该工作以将“名称”和“描述”存储在一个数组中。代码如下...

struct task 
    var name = "Untitled"
    var description = "No description available"


var tasks = [task]()

func addTask(name: String, description: String) 
    tasks.append(task(name: name, description: description))

在 UserDefaults 中存储数据并在重新启动后将信息添加到 cell.textLabel?.textcell.detailTextLabel?.text 的最佳方式是什么?

【问题讨论】:

应该以大写字母开头的结构命名。您需要创建一个类,使其符合 NSCoding 并使用 KeyedArchiever 来保存对象数据 @LeoDabus NSUserDefaults不能保存数组的数据吗? 您可以使用 UserDeafaults 从 KeyedArchiever 中保存 Data 对象 @LeoDabus 好的。我会看看这个,谢谢:) 【参考方案1】:

以大写字母开头的结构命名是 Swift 的惯例。您需要创建一个类,使其符合 NSCoding 并使用 KeyedArchiever 来保存对象数据

class Task: NSObject, NSCoding 
    let name: String
    let desc: String
    required init(name: String, desc: String) 
        self.name = name
        self.desc = desc
    
    func encode(with coder: NSCoder) 
        coder.encode(name, forKey: "name")
        coder.encode(desc, forKey: "desc")
    
    required init(coder decoder: NSCoder) 
        self.name = decoder.decodeObject(forKey: "name") as? String ?? ""
        self.desc = decoder.decodeObject(forKey: "desc") as? String ?? ""
    


测试

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate  
    @IBOutlet weak var nameField: UITextField!
    @IBOutlet weak var descField: UITextField!
    @IBOutlet weak var tableView: UITableView!
    var tasks: [Task] = []
    override func viewDidLoad() 
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        if let data = UserDefaults.standard.data(forKey: "tasks") 
            tasks = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Task] ?? []
            tableView.reloadData()
        
    
    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
    
    @IBAction func addTask(_ sender: UIButton) 
        guard let name = nameField.text, let desc = descField.text else  return 
        tasks.append(Task(name: name, desc: desc))
        UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: tasks) , forKey: "tasks")
        tableView.reloadData()
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return tasks.count
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellID")!
        cell.textLabel?.text = tasks[indexPath.row].name + " - " + tasks[indexPath.row].desc
        return cell
    

【讨论】:

感谢您的回复。我创建了一个测试项目,一个具有两个文本字段和一个按钮的单视图应用程序,一个用于名称、描述和附加任务。代码的顶部在一个单独的 Task.swift 文件中,其余代码在 viewDidLoad 中。数组项目似乎没有为下次发布保存?想法? 这一直工作到现在,当执行UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: tasks) , forKey: "tasks")时,应用程序终止并返回线程1:SIGABRT。此消息出现在控制台中:2016-10-02 12:22:00.930576 Timetable[8448:2049895] -[Timetable.Task encodeWithCoder:]: unrecognized selector sent to instance 0x174134e60 2016-10-02 12:22:00.937006 Timetable[8448:2049895] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Timetable.Task encodeWithCoder:]: unrecognized selector sent to instance 0x174134e60'

以上是关于Swift 3.0:在 TableView 的 UserDefaults 中存储数组的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3.0:在 TableView 的 UserDefaults 中存储数组

swift 3.0 转换添加到视图字典时不明确使用 tableView

调整 TableView 大小时,Swift 3.0 表格单元格未填充

swift 3.0中的uibutton问题

长按选择的 Swift 3.0 表格视图单元格

在 SWIFT 3.0 中展开可选值时意外发现 nil