OverrideSetup.swift 4.6 KB

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