You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何持久化TableView行?iOS每日任务完成状态记录咨询

嘿,这个场景我太熟悉了!咱们来聊聊怎么优雅解决当日完成任务的记录问题,分两种情况给你方案,你可以根据自己的需求选:

方案1:轻量临时记录——不用新建Core Data实体

如果你的需求只是当日内记住哪些任务已完成,不需要保留历史完成记录(比如统计过去一周的完成情况),那完全不用动Core Data的结构,用UserDefaults就够了,简单高效。

具体怎么做:

  • 用当日日期字符串(比如yyyy-MM-dd格式)作为UserDefaults的键,存储当天已完成任务的ID集合(每个任务在Core Data里最好有个唯一的taskId字段,或者直接用objectID转成字符串)。
  • 用户点击TableView行标记完成时:
    1. 把该任务的ID加入到UserDefaults对应的当日集合里;
    2. 同时从TableView的数据源数组中移除这个任务,刷新UI。
  • 每日加载任务时:
    从Core Data取出所有用户自定义任务,再过滤掉UserDefaults里记录的当日已完成ID对应的任务,只显示未完成的。
  • newDay()函数判断到新一天时:
    不用特意清理前一天的记录(当然也可以定期清理比如7天前的,避免UserDefaults冗余),因为第二天会用新的日期键,自动和前一天的记录隔离。

给你一段简化的代码示例:

// 生成当日的存储键
private func todayCompletionKey() -> String {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    formatter.timeZone = .current
    return "CompletedTasks_\(formatter.string(from: Date()))"
}

// 标记任务完成
func markTaskCompleted(taskId: String) {
    var completedIds = UserDefaults.standard.array(forKey: todayCompletionKey()) as? [String] ?? []
    completedIds.append(taskId)
    UserDefaults.standard.set(completedIds, forKey: todayCompletionKey())
}

// 加载当日未完成任务
func loadTodayTasks() -> [Task] {
    // 先从Core Data取出所有自定义任务
    let allTasks = fetchAllCustomTasks() // 替换成你自己的Core Data查询方法
    // 取出当日已完成的任务ID
    let completedIds = UserDefaults.standard.array(forKey: todayCompletionKey()) as? [String] ?? []
    // 过滤未完成的
    return allTasks.filter { !completedIds.contains($0.taskId!) }
}
方案2:持久化历史记录——新建Core Data实体

如果以后想做任务完成统计、历史回顾这类功能,那新建一个实体是更靠谱的选择,扩展性更强。

建议新建一个DailyTaskCompletion实体,包含这些字段:

  • task:和原任务实体建立一对一关联(每个完成记录对应一个任务);
  • completionDate:日期类型,存储任务完成的当天(最好存当天的起始时间,比如Calendar.current.startOfDay(for: Date()),方便后续按日期查询);
  • 可选:completionTime,记录具体完成的时间,做更细粒度的统计。

操作流程:

  • 用户点击完成时:创建一个DailyTaskCompletion实例,关联对应的任务,设置completionDate为当天,保存到Core Data,同时从TableView数据源移除任务。
  • 每日加载任务时:查询Core Data,过滤掉当天已经有完成记录的任务,只显示未完成的。
  • newDay()函数里不需要额外处理,因为查询时会按日期过滤,历史完成记录会一直保留,方便后续做统计。

代码示例:

// DailyTaskCompletion的NSManagedObject子类
class DailyTaskCompletion: NSManagedObject {
    @NSManaged var task: Task
    @NSManaged var completionDate: Date
}

// 标记任务完成
func markTaskCompleted(task: Task) {
    let context = persistentContainer.viewContext
    let completion = DailyTaskCompletion(context: context)
    completion.task = task
    completion.completionDate = Calendar.current.startOfDay(for: Date())
    
    do {
        try context.save()
    } catch {
        print("保存完成记录失败:\(error.localizedDescription)")
    }
}

// 加载当日未完成任务
func loadTodayTasks() -> [Task] {
    let context = persistentContainer.viewContext
    let startOfDay = Calendar.current.startOfDay(for: Date())
    let endOfDay = Calendar.current.date(byAdding: .day, value: 1, to: startOfDay)!
    
    // 查询条件:任务没有当天的完成记录
    let predicate = NSPredicate(format: "NOT (ANY dailyCompletions.completionDate >= %@ AND dailyCompletions.completionDate < %@)", startOfDay as CVarArg, endOfDay as CVarArg)
    let fetchRequest: NSFetchRequest<Task> = Task.fetchRequest()
    fetchRequest.predicate = predicate
    
    do {
        return try context.fetch(fetchRequest)
    } catch {
        print("加载任务失败:\(error.localizedDescription)")
        return []
    }
}
选哪个方案?
  • 只是临时记录当日完成状态,选方案1,快速实现,不用改Core Data结构;
  • 有长期统计需求,或者以后要扩展功能,选方案2,一步到位。

内容的提问来源于stack exchange,提问作者ashwin nath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:12:11