如何持久化tableview行?

时间:2018-05-04 18:02:10

标签: ios swift core-data

我正在创建一个ios应用程序,它会每天向我显示一组用户特定的任务,我点击该删除以显示其完成情况。我将任务保存在核心数据中,只需在点击时删除tableview行。我不删除coredata中的数据作为其用户定义,并且需要每天重新加载它。如果应用程序在新的一天打开,我使用newDay()函数决定从coredata加载数据。我该怎么做才能记住当天完成的所有任务?我是否需要创建另一个能够记住哪些任务已完成或是否有更简单的方法?

var tasks: [NSManagedObject] = []
let defaults = UserDefaults.standard
var calender = Calendar.current

override func viewDidLoad() {
    super.viewDidLoad()

    title = "DailyTasker"
    navigationItem.leftBarButtonItem = editButtonItem

}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let checkDate = newDay()
    if checkDate{

    //1
    guard let appDelegate =
        UIApplication.shared.delegate as? AppDelegate else {
            return
    }

    let managedContext =
        appDelegate.persistentContainer.viewContext

    //2
    let fetchRequest =
        NSFetchRequest<NSManagedObject>(entityName: "Task")

    //3
    do {
        tasks = try managedContext.fetch(fetchRequest)
        defaults.set(Date(), forKey: "LastRun")
    } catch let error as NSError {
        print("Could not fetch. \(error), \(error.userInfo)")
    }
    }
}

func newDay() -> Bool{
    if let lastRun = defaults.object(forKey: "LastRun") as? Date{
        if !calender.isDateInToday(lastRun){
            return true
        } else {
            return false
        }
    } else {
        return true
    }

}


@IBAction func addName(_ sender: UIBarButtonItem) {
    let alert = UIAlertController(title: "New Task",
                                  message: "Add a new task",
                                  preferredStyle: .alert)

    let saveAction = UIAlertAction(title: "Save",
                                   style: .default) {
                                    [unowned self] action in

                                    guard let textField = alert.textFields?.first,
                                        let nameToSave = textField.text else {
                                            return
                                    }

                                    self.save(name: nameToSave)
                                    self.tableView.reloadData()
    }

    let cancelAction = UIAlertAction(title: "Cancel",
                                     style: .default)

    alert.addTextField()

    alert.addAction(saveAction)
    alert.addAction(cancelAction)

    present(alert, animated: true)
}

func save(name: String) {

    guard let appDelegate =
        UIApplication.shared.delegate as? AppDelegate else {
            return
    }

    // 1
    let managedContext =
        appDelegate.persistentContainer.viewContext

    // 2
    let entity =
        NSEntityDescription.entity(forEntityName: "Task",
                                   in: managedContext)!

    let task = NSManagedObject(entity: entity,
                               insertInto: managedContext)

    // 3
    task.setValue(name, forKeyPath: "name")

    // 4
    do {
        try managedContext.save()
        tasks.append(task)
    } catch let error as NSError {
        print("Could not save. \(error), \(error.userInfo)")
    }

}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return tasks.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let task = tasks[indexPath.row]
    let cell = tableView.dequeueReusableCell(withIdentifier: "TaskerCell", for: indexPath)
    cell.textLabel?.text = task.value(forKeyPath: "name") as? String

    return cell
}       

 // Override to support editing the table view.
 override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
 if editingStyle == .delete {
 // Delete the row from the data source
 tasks.remove(at: indexPath.row)
 tableView.deleteRows(at: [indexPath], with: .fade)
 } else if editingStyle == .insert {

 }
 }

 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tasks.remove(at: indexPath.row)
    tableView.deleteRows(at: [indexPath], with: .fade)
}    

}

2 个答案:

答案 0 :(得分:0)

我不确定为什么你不能删除数据。是因为规格。 如果没有那么,当您在coredata中保存任务时,只需为其分配一个唯一的Identifer(id),然后您就可以创建自己的数据堆栈方法来删除特定任务。

您可以为任务示例

创建数据模型类或结构
class TaskData {
  var id: Int!
  var task: String!

  init(id: Int, task: String) {
    self.id = id
    self.task = task
  }
}

将此任务作为此dataClass保存到coreData。

当您删除当时的行时,请删除任务ID并将其从coreDataStack中删除。

一种好方法是创建一个TaskManager Singelton类来处理所有核心数据方法。

答案 1 :(得分:0)

您可以为任务添加日期属性,并将其命名为lastDone。然后将其设置为任务完成时的当前日期时间,并在获取任务实例时使用谓词,这样您才能获得今天未完成的任务。

 task.lastDone = Date()

我不确定你如何定义&#34;今天&#34;但是this question应该可以帮助您创建一个正确过滤任务的谓词,尽管您可能还希望包含lastDone为空的任务。