Ios 如何持久化tableview行?

Ios 如何持久化tableview行?,ios,swift,core-data,Ios,Swift,Core Data,我正在创建一个ios应用程序,它每天都会向我显示一组特定于用户的任务,我可以单击删除这些任务以显示其完成情况。我将任务保存在核心数据中,只需单击删除tableview行。我不删除coredata中用户定义的数据,需要每天重新加载。如果应用程序在新的一天打开,我使用newDay()函数决定从coredata加载数据。我该怎么做才能记住当天哪些任务已经完成?我是否需要创建另一个enity来记住哪些任务都已完成,还是有更简单的方法 var tasks: [NSManagedObject] = [] l

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

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)
}    
var任务:[NSManagedObject]=[]
让defaults=UserDefaults.standard
var Calendar=Calendar.current
重写func viewDidLoad(){
super.viewDidLoad()
title=“DailyStasker”
navigationItem.leftBarButtonItem=editButtonItem
}
覆盖函数视图将出现(uo动画:Bool){
超级。视图将显示(动画)
让checkDate=newDay()
如果检查日期{
//1
警卫让appDelegate=
UIApplication.shared.delegate作为?AppDelegate else{
返回
}
让managedContext=
appDelegate.persistentContainer.viewContext
//2
让我们请求=
NSFetchRequest(entityName:“任务”)
//3
做{
tasks=尝试managedContext.fetch(fetchRequest)
defaults.set(Date(),forKey:“LastRun”)
}将let错误捕获为NSError{
打印(“无法获取.\(错误),\(错误.userInfo)”)
}
}
}
func newDay()->Bool{
如果让lastRun=defaults.object(forKey:“lastRun”)作为?日期{
如果!日历日期为天(最后一次运行){
返回真值
}否则{
返回错误
}
}否则{
返回真值
}
}
@iAction func addName(uu发件人:UIBarButtonim){
let alert=UIAlertController(标题:“新任务”,
消息:“添加新任务”,
preferredStyle:。警报)
让saveAction=UIAlertAction(标题:“保存”,
样式:。默认值){
[无主的自我]行动
guard let textField=alert.textFields?首先,
让nameToSave=textField.text else{
返回
}
self.save(名称:nameToSave)
self.tableView.reloadData()
}
让cancelAction=UIAlertAction(标题:“取消”,
样式:。默认值)
alert.addTextField()
alert.addAction(saveAction)
alert.addAction(取消操作)
当前(警报、动画:真)
}
func保存(名称:字符串){
警卫让appDelegate=
UIApplication.shared.delegate作为?AppDelegate else{
返回
}
// 1
让managedContext=
appDelegate.persistentContainer.viewContext
// 2
让实体=
NSEntityDescription.entity(名称:“任务”,
在:managedContext)中!
让任务=NSManagedObject(实体:实体,
插入到:managedContext)
// 3
task.setValue(名称,forKeyPath:“名称”)
// 4
做{
请尝试managedContext.save()
tasks.append(任务)
}将let错误捕获为NSError{
打印(“无法保存.\(错误),\(错误.用户信息)”)
}
}
//标记:-表视图数据源
重写func numberOfSections(在tableView:UITableView中)->Int{
//#警告未完成执行,返回节数
返回1
}
重写func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
//#警告未完成实现,返回行数
返回任务数
}
重写func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
let task=tasks[indexPath.row]
let cell=tableView.dequeueReusableCell(标识符为:“TaskerCell”,表示:indexPath)
cell.textlab?.text=task.value(forKeyPath:“name”)为?字符串
返回单元
}       
//替代以支持编辑表格视图。
重写func tableView(tableView:UITableView,commit editingStyle:UITableViewCellEditingStyle,forRowAt indexPath:indexPath){
如果editingStyle==.delete{
//从数据源中删除该行
tasks.remove(位于:indexPath.row)
tableView.deleteRows(位于:[indexPath],带:.fade)
}如果editingStyle==,则为else。插入{
}
}
重写func tableView(tableView:UITableView,didSelectRowAt indexPath:indexPath){
tasks.remove(位于:indexPath.row)
tableView.deleteRows(位于:[indexPath],带:.fade)
}    

}

我不确定您为什么不能删除数据。是因为规格问题吗。 如果没有,则在coredata中保存任务时,只需使用唯一标识符(id)对其进行分配,然后就可以创建自己的数据堆栈方法来删除特定任务

您可以为任务示例创建数据模型类或结构

class TaskData {
  var id: Int!
  var task: String!

  init(id: Int, task: String) {
    self.id = id
    self.task = task
  }
}
将任务作为此数据类保存到coreData中

当您当时删除该行时,请捕获任务Id并将其从coreDataStack中删除


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

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

 task.lastDone = Date()

我不确定您如何定义“今天”,但应该帮助您创建一个谓词,以正确过滤您的任务,尽管您可能还希望包括
lastDone
为空的任务。

我不想删除coreData中的任务,因为我想每天重新加载我的tableview,其中包含coreData中的所有任务。这是一个任务重复应用程序。