2016-09-25 54 views
2

我试图存储在UserDefaults数组又不得不找到解决办法没有运气。我有一个structfunc设置这个工作来存储“名称”和“描述”在一个数组中。代码如下...雨燕3.0:存储阵列中UserDefaults为的tableView

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的最佳方式?

+1

应该为您的结构开始以一个大写字母。您需要创建一个类,使其符合NSCoding并使用KeyedArchiever保存对象数据 –

+0

@LeoDabus是否无法使用NSUserDefaults保存数组的数据? –

+0

您可以使用UserDeafaults保存来自KeyedArchiever的数据对象 –

回答

0

这是斯威夫特惯例命名您的结构开始以一个大写字母。你需要做的一类,使之符合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 
    } 
} 
+0

感谢您的回应。我创建了一个测试项目,一个具有两个文本字段和一个按钮的单一视图应用程序,一个用于名称,描述和追加任务。代码的顶部部分位于单独的Task.swift文件中,其余代码位于viewDidLoad中。阵列物品似乎没有保存下一个发射想法? –

+1

@SebVidal https://www.dropbox.com/s/sb4jm6asm3cistw/Tasks.zip?dl=1 –

+0

这一直工作到现在为止,在执行的时候'UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject:任务) ,forKey:“tasks”),应用程序终止并返回线程1:SIGABRT。该消息显示在控制台中:2016年10月2日'12:22:00.930576时刻表[8448:2049895] - [Timetable.Task encodeWithCoder:]:无法识别的选择发送到实例0x174134e60 2016年10月2日12:22:00.937006时刻表[8448:2049895] ***由于未捕获的异常'NSInvalidArgumentException',原因:' - [Timetable.Task encodeWithCoder:]:无法识别的选择器发送到实例0x174134e60' –