如何在同一天保存CoreData对象并实现同日期时长累计?
问题解决方案
失效原因
你现有判断逻辑失效的核心原因是Date类型在Swift中默认精确到毫秒,直接使用$0.date == Date()做等值判断时,只有两条记录的时间精确到毫秒完全一致才会判定相等,无法匹配「同一天」的业务需求。
修复方案
方案1:内存过滤(适合数据量小的场景)
先给Date加扩展实现同天判断:
extension Date { /// 判断两个日期是否为同一天 func isSameDay(as otherDate: Date) -> Bool { Calendar.current.isDate(self, inSameDayAs: otherDate) } }
修改你的判断逻辑:
let today = Date() if let existingRecord = ro.first(where: { $0.date.isSameDay(as: today) }) { // 存在当日记录,累加时长 existingRecord.totaltime += 200 } else { // 无当日记录,新建对象 let newitem = Record(context: viewContext) newitem.date = today newitem.totaltime = item.totaltime } // 最后不要忘记保存上下文 do { try viewContext.save() } catch { print("CoreData保存失败: \(error.localizedDescription)") }
方案2:谓词查询(适合数据量大的场景)
直接通过CoreData查询语句从数据库筛选当日记录,不需要把所有数据加载到内存过滤,效率更高:
let calendar = Calendar.current let today = Date() // 获取今日零点和明日零点 let startOfDay = calendar.startOfDay(for: today) let endOfDay = calendar.date(byAdding: .day, value: 1, to: startOfDay)! let fetchRequest: NSFetchRequest<Record> = Record.fetchRequest() // 筛选日期在[今日零点, 明日零点)区间的记录 fetchRequest.predicate = NSPredicate(format: "date >= %@ AND date < %@", startOfDay as CVarArg, endOfDay as CVarArg) do { let result = try viewContext.fetch(fetchRequest) if let existRecord = result.first { existRecord.totaltime += 200 } else { let newItem = Record(context: viewContext) newItem.date = today newItem.totaltime = item.totaltime } try viewContext.save() } catch { print("CoreData操作失败: \(error.localizedDescription)") }
内容的提问来源于stack exchange,提问作者user16856881
相关产品推荐
相关产品推荐

