2016-12-05 2 views
4

현재 신속한 영구 데이터를 실험하고 있지만이 데이터를 저장하고 다시 검색하는 데 문제가 있습니다. 기본적으로 저는 두 개의 텍스트 필드가 있습니다. 사용자가 제출 버튼을 누르면 항목이 UITable에 저장됩니다. 여기서 사용자는 테이블의 항목을 이동하거나 원하는 경우 삭제할 수 있습니다. 내 주요 문제는이 데이터를 저장하고로드하는 것입니다.Swift의 영구 데이터

Taskmanager.swift - 여기 내 기본 유형이

import Foundation 

import UIKit 

var taskMgr: TaskManager = TaskManager() 

struct task { 
    var name = "Name" 
    var year = "Year" 
} 


//setting data 
let defaults = UserDefaults.standard 
//defaults.synchronize() 


//getting data 

class TaskManager: NSObject { 
    var tasks = [task]() 

    func addTask(name: String, year: String){ 
     tasks.append(task(name: name, year: year)) 
    } 
} 

ThirdViewController.swift

저장이 - 여기 내 테이블과 그 기능을 저장, 나는 또한 저장 및로드 데이터 기능의 밑그림을 .

import Foundation 

import UIKit 

class ThirdViewController:UIViewController, UITableViewDelegate, UITableViewDataSource { 

    @IBOutlet var tableView: UITableView! 

    @IBAction func deleteT(_ sender: Any) { 

     if(tableView.isEditing == true){ 
     tableView.setEditing(false, animated: true) 
     }else{ 
     tableView.setEditing(true, animated: true) 
     } 


    } 

    func saveData() { 

     let data = NSMutableData() 

     let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) 
     let path = paths[0] 
     let file = (path as NSString).appendingPathComponent("Persistent.plist") 

     //2 
     let archiver = NSKeyedArchiver(forWritingWith: data) 
     archiver.encode(G, forKey: "name") 
     archiver.endode(year, forKey: "year") 
     archiver.finishEncoding() 
     data.write(toFile: file, atomically: true) 
    } 


    func loadData() { 
     let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) 
     let path = paths[0] 
     let file = (path as NSString).appendingPathComponent("Persistent.plist") 

     // 1 
     if FileManager.default.fileExists(atPath: file) { 
      if let data = NSData(contentsOfFile: file) { 
       let unarchiver = NSKeyedUnarchiver(forReadingWith: data as Data) 
       name = unarchiver.decodeObjectForKey("name") as! [String] 
       year = unarchiver.decodeObjectForKey("year") as! [String] 


       unarchiver.finishDecoding() 
      } 
     } 
    } 





    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { 
     return true 
    } 

    func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool { 
     return false 
    } 

    func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { 


    } 

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 
     return true 
    } 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     tableView.reloadData() 
     loadData() 
    } 

    override func viewWillAppear(_ animated: Bool) { 
     self.tableView.reloadData() 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ 
     return taskMgr.tasks.count 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ 

     let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "TableView") 

     //Assign the contents of our var "items" to the textLabel of each cell 
     cell.textLabel!.text = taskMgr.tasks[indexPath.row].name 
     cell.detailTextLabel!.text = taskMgr.tasks[indexPath.row].year 
     //cell.editing = tableView(tableView, canMoveRowAtIndexPath: indexPath) 

     return cell 

    } 

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath){ 
     if (editingStyle == UITableViewCellEditingStyle.delete){ 

      taskMgr.tasks.remove(at: indexPath.row) 
      tableView.reloadData() 
     } 
    } 
} 

FourthViewController.swift는 - 나는 테이블에 내 항목을 추가하고 어떻게 여기에 내 텍스트 필드와 버튼을 가지고.

import Foundation 

import UIKit 

class FourthViewController: UIViewController, UITextFieldDelegate{ 

    @IBOutlet var addT: UITextField! 
    @IBOutlet var addY: UITextField! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // 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. 
    } 


    @IBAction func confTask(_ sender:UIButton){ 
     if (addT.text == ""){ 
     }else{ 
     //add record 
     let name: String = addT.text! 
     let Year: String = addY.text! 
     //taskMgr.addTask(name:name) 
     taskMgr.addTask(name:name, year:Year) 

     } 

     //dismiss keyboard and reset fields 

     self.view.endEditing(true) 
     addT.text = nil 
     addY.text = nil 

    } 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     self.view.endEditing(true) 
    } 

    func textFieldShouldReturn(_ textField: UITextField) -> Bool{ 
     textField.resignFirstResponder() 
     return true 
    } 





} 
+0

확인이 편집 http://stackoverflow.com/questions/40756178/how-can-i-delete-object-from-core -data-in-swift-3/40756625 # 40756625, 해결책을 얻었을 수도 있습니다. –

+0

빠른 응답을 보내 주셔서 감사합니다. 그러나 plist 파일에 데이터를 추가하려고합니다. (나던가 plist가되어야하지만 가장 쉬운 방법이라고 생각합니다. 방법?) 일단 그것을 닫으면 거기에서 그것을 검색하십시오. 나는 당신의 대답을 완전히 이해하지 못한다. 나는 그것을 어떻게 조작 할까? 감사! –

+0

실제로 내가 핵심 데이터 참조를 준 –

답변

1

나는 작업을 지속하기 위해 NSUserDefaults을 사용하여 몇 가지 샘플 코드를 만들었습니다. 아주 단순한 예입니다. 실험을하고 100 개 이하의 요소 만 갖고 싶다면 괜찮을 것입니다. 아래 코드를 사용하면 작업을 표시, 제거 및 저장할 수 있습니다.

그러나 앞으로는 Core Data에 대한 자세한 내용을 읽어 보시기 바랍니다. 많은 훌륭한 자습서가 있습니다 (예 : one).

Task 개체 모델을 만들고 작업 읽기, 저장 및 제거를 위해 TaskManager을 만들었습니다.

import Foundation 

// Task Data Model 
class Task: NSObject, NSCoding { 
    let name: String 
    let year: String 

    required init(name: String, year: String) { 
     self.name = name 
     self.year = year 
    } 

    required init(coder decoder: NSCoder) { 
     self.name = decoder.decodeObject(forKey: "name") as? String ?? "" 
     self.year = decoder.decodeObject(forKey: "year") as? String ?? "" 
    } 

    func encode(with coder: NSCoder) { 
     coder.encode(name, forKey: "name") 
     coder.encode(year, forKey: "year") 
    } 
} 

class TaskManager { 
    /// UserDefaults instance 
    private let defaults = UserDefaults.standard 

    /// Singleton instance, class **should** be accessed by this property 
    static let shared = TaskManager() 

    /// Indetifier of tasks container in `defaults` 
    private let kTasksIdentifier = "tasks" 

    /// Add a new task to your container and syncronize it into `defaults` 
    /// 
    /// - Parameters: 
    /// - name: Name of the task 
    /// - year: Year of the task 
    func save(taskName name: String, year: String) { 
     let task = Task(name: name, year: year) 

     // Check if there is already saved tasks 
     guard let data = defaults.value(forKey: kTasksIdentifier) as? Data, var tasks = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Task] else { 
      // If not, save it as the first one 
      syncronizeTasks(tasks: [task]) 
      return 
     } 

     tasks.append(task) 
     syncronizeTasks(tasks: tasks) 
    } 

    /// Remove a task at an index 
    /// 
    /// - Parameters: 
    /// - index: The index of the removeable task 
    func remove(at index: Int) { 

     guard let data = defaults.value(forKey: kTasksIdentifier) as? Data, var tasks = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Task] else { 
      fatalError("Unable to retrive tasks from defaults") 
     } 

     tasks.remove(at: index) 
     syncronizeTasks(tasks: tasks)   
    } 

    /// Read all tasks elements 
    /// If there are tasks in memory, it returns the one from memory 
    /// Otherwise reads it from `UserDefaults` 
    /// 
    /// - Returns: all tasks elements available, return empty array if no elements found 
    func readAllTasks() -> [Task] { 
     let data = UserDefaults.standard.value(forKey: kTasksIdentifier) 
     let allTasks = NSKeyedUnarchiver.unarchiveObject(with: data as! Data) 
     return allTasks as? [Task] ?? [Task]() 
    } 


    private func syncronizeTasks(tasks: [Task]) { 
     let data = NSKeyedArchiver.archivedData(withRootObject: tasks) 
     defaults.set(data, forKey: kTasksIdentifier) 
     defaults.synchronize() 
    } 
} 

기존 ThirdViewController을 수정했습니다.

import UIKit 
import Foundation 

class ThirdViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 

    @IBOutlet var tableView: UITableView! 
    /// Your tasks being updated in this collection every time `refreshTasks()` is being called 
    private var tasks = [Task]() 

    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 
     self.refreshTasks() 
     self.tableView.reloadData() 
    } 

    func refreshTasks() { 
     self.tasks = TaskManager.shared.readAllTasks() 
    } 

    @IBAction func deleteT(_ sender: Any) { 
     if(tableView.isEditing == true) { 
      tableView.setEditing(false, animated: true) 
     } else { 
      tableView.setEditing(true, animated: true) 
     } 
    } 

    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { 
     return true 
    } 

    func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool { 
     return false 
    } 

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 
     return true 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ 
     return tasks.count 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ 

     let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "TableView") 

     //Assign the contents of our var "items" to the textLabel of each cell 
     cell.textLabel!.text = tasks[indexPath.row].name 
     cell.detailTextLabel!.text = tasks[indexPath.row].year 
     //cell.editing = tableView(tableView, canMoveRowAtIndexPath: indexPath) 

     return cell 

    } 

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath){ 
     if (editingStyle == UITableViewCellEditingStyle.delete) { 
      self.tableView.beginUpdates() 
      TaskManager.shared.remove(at: indexPath.row) 
      refreshTasks() 
      self.tableView.deleteRows(at: [indexPath], with: .fade) 
      self.tableView.endUpdates() 
     } 
    } 
} 

그리고, 그냥 경우에, 당신의 FourthViewController 너무

import Foundation 
import UIKit 

class FourthViewController: UIViewController, UITextFieldDelegate { 

    @IBOutlet var addT: UITextField! 
    @IBOutlet var addY: UITextField! 

    /// User has pressed `Submit` button 
    /// 
    /// - Parameter sender: the pressed button 
    @IBAction func confTask(_ sender: UIButton) { 
     // Check if textfields are containing text 
     guard let nameText = addT.text, let yearText = addY.text, !nameText.isEmpty, !yearText.isEmpty else { 
      print("at least one of the textFields is not filled") 
      return 
     } 

     // Save the tasks 
     TaskManager.shared.save(taskName: nameText, year: yearText) 

     //dismiss keyboard and reset fields 
     self.view.endEditing(true) 
     addT.text = nil 
     addY.text = nil 
    } 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     self.view.endEditing(true) 
    } 

    func textFieldShouldReturn(_ textField: UITextField) -> Bool{ 
     textField.resignFirstResponder() 
     return true 
    } 
}