// // Persistence.swift // Shared // // Created by Trey Tartt on 1/5/22. // import CoreData struct PersistenceController { static let shared = PersistenceController.persistenceController private static var persistenceController: PersistenceController { #if targetEnvironment(simulator) return PersistenceController(inMemory: false) #else return PersistenceController(inMemory: false) #endif } public var viewContext: NSManagedObjectContext { return PersistenceController.shared.container.viewContext } public func add(mood: Mood, forDate date: Date) { let newItem = MoodEntry(context: viewContext) newItem.timestamp = Date() newItem.moodValue = Int16(mood.rawValue) newItem.date = date do { try viewContext.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } public func moodEntries(forStartDate date: Date, count: Int) -> [MoodEntry] { let fetchRequest = NSFetchRequest(entityName: "MoodEntry") fetchRequest.fetchLimit = count fetchRequest.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)] var calendar = Calendar.current calendar.timeZone = NSTimeZone.local let dateFrom = calendar.startOfDay(for: Date()) // Set predicate as date being today's date let fromPredicate = NSPredicate(format: "date <= %@", dateFrom as NSDate) let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate]) fetchRequest.predicate = datePredicate let entries = try! viewContext.fetch(fetchRequest) if entries.count >= count { return Array(entries) } else { return entries } } func populateTestData() { for idx in 1..<25 { let newItem = MoodEntry(context: viewContext) newItem.timestamp = Date() newItem.moodValue = Int16(Mood.allValues.randomElement()!.rawValue) newItem.date = Calendar.current.date(byAdding: .day, value: -idx, to: Date()) } do { try viewContext.save() } catch { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } func populateMemory() { for idx in 1..<25 { let newItem = MoodEntry(context: viewContext) newItem.timestamp = Calendar.current.date(byAdding: .day, value: -idx, to: Date()) newItem.moodValue = Int16(Mood.allValues.randomElement()!.rawValue) newItem.date = Calendar.current.date(byAdding: .day, value: -idx, to: Date()) } do { try viewContext.save() } catch { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } func fillInMissingDates() { let fetchRequest = NSFetchRequest(entityName: "MoodEntry") fetchRequest.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)] let entries = try! viewContext.fetch(fetchRequest) if let earliestDate = entries.last?.date { let diffInDays = Calendar.current.dateComponents([.day], from: earliestDate, to: Date()).day for idx in 1.. = NSFetchRequest(entityName: "MoodEntry") let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest) do { try viewContext.executeAndMergeChanges(using: deleteRequest) try viewContext.save() } catch let error as NSError { fatalError("Unresolved error \(error), \(error.userInfo)") } } public func randomEntries(count: Int) -> [MoodEntry] { var entries = [MoodEntry]() for idx in 0..