OverrideSetup.swift 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import CoreData
  2. import Foundation
  3. extension Home.StateModel {
  4. // Setup Overrides
  5. func setupOverrides() {
  6. Task {
  7. do {
  8. let ids = try await self.fetchOverrides()
  9. let overrideObjects: [OverrideStored] = try await CoreDataStack.shared
  10. .getNSManagedObject(with: ids, context: viewContext)
  11. await updateOverrideArray(with: overrideObjects)
  12. } catch let error as CoreDataError {
  13. debug(.default, "Core Data error in setupOverrides: \(error)")
  14. } catch {
  15. debug(.default, "Unexpected error in setupOverrides: \(error)")
  16. }
  17. }
  18. }
  19. private func fetchOverrides() async throws -> [NSManagedObjectID] {
  20. let results = try await CoreDataStack.shared.fetchEntitiesAsync(
  21. ofType: OverrideStored.self,
  22. onContext: overrideFetchContext,
  23. predicate: NSPredicate.lastActiveOverride, // this predicate filters for all Overrides within the last 24h
  24. key: "date",
  25. ascending: false
  26. )
  27. return try await overrideFetchContext.perform {
  28. guard let fetchedResults = results as? [OverrideStored] else {
  29. throw CoreDataError.fetchError(function: #function, file: #file)
  30. }
  31. return fetchedResults.map(\.objectID)
  32. }
  33. }
  34. @MainActor private func updateOverrideArray(with objects: [OverrideStored]) {
  35. overrides = objects
  36. }
  37. // Setup expired Overrides
  38. func setupOverrideRunStored() {
  39. Task {
  40. do {
  41. let ids = try await self.fetchOverrideRunStored()
  42. let overrideRunObjects: [OverrideRunStored] = try await CoreDataStack.shared
  43. .getNSManagedObject(with: ids, context: viewContext)
  44. await updateOverrideRunStoredArray(with: overrideRunObjects)
  45. } catch let error as CoreDataError {
  46. debug(.default, "Core Data error in setupOverrideRunStored: \(error)")
  47. } catch {
  48. debug(.default, "Unexpected error in setupOverrideRunStored: \(error)")
  49. }
  50. }
  51. }
  52. private func fetchOverrideRunStored() async throws -> [NSManagedObjectID] {
  53. let predicate = NSPredicate(format: "startDate >= %@", Date.oneDayAgo as NSDate)
  54. let results = try await CoreDataStack.shared.fetchEntitiesAsync(
  55. ofType: OverrideRunStored.self,
  56. onContext: overrideFetchContext,
  57. predicate: predicate,
  58. key: "startDate",
  59. ascending: false
  60. )
  61. return try await overrideFetchContext.perform {
  62. guard let fetchedResults = results as? [OverrideRunStored] else {
  63. throw CoreDataError.fetchError(function: #function, file: #file)
  64. }
  65. return fetchedResults.map(\.objectID)
  66. }
  67. }
  68. @MainActor private func updateOverrideRunStoredArray(with objects: [OverrideRunStored]) {
  69. overrideRunStored = objects
  70. }
  71. /// Cancels the running Override, creates an entry in the OverrideRunStored Core Data entity and posts a custom notification so that the AdjustmentsView gets updated
  72. @MainActor func cancelOverride(withID id: NSManagedObjectID) async {
  73. do {
  74. guard let profileToCancel = try viewContext.existingObject(with: id) as? OverrideStored else { return }
  75. profileToCancel.enabled = false
  76. guard viewContext.hasChanges else { return }
  77. try viewContext.save()
  78. await saveToOverrideRunStored(object: profileToCancel)
  79. Foundation.NotificationCenter.default.post(name: .didUpdateOverrideConfiguration, object: nil)
  80. } catch let error as NSError {
  81. debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to cancel Profile with error: \(error)")
  82. }
  83. }
  84. /// We can safely pass the NSManagedObject as we are doing everything on the Main Actor
  85. @MainActor func saveToOverrideRunStored(object: OverrideStored) async {
  86. let newOverrideRunStored = OverrideRunStored(context: viewContext)
  87. newOverrideRunStored.id = UUID()
  88. newOverrideRunStored.name = object.name
  89. newOverrideRunStored.startDate = object.date ?? .distantPast
  90. newOverrideRunStored.endDate = Date()
  91. newOverrideRunStored.target = NSDecimalNumber(decimal: overrideStorage.calculateTarget(override: object))
  92. newOverrideRunStored.override = object
  93. newOverrideRunStored.isUploadedToNS = false
  94. do {
  95. guard viewContext.hasChanges else { return }
  96. try viewContext.save()
  97. } catch let error as NSError {
  98. debugPrint(
  99. "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to save an Override to the OverrideRunStored entity with error: \(error)"
  100. )
  101. }
  102. }
  103. }