2016-09-25 57 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' –