GlucoseStored+helper.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import CoreData
  2. import Foundation
  3. extension GlucoseStored {
  4. static func fetch(
  5. _ predicate: NSPredicate = .all,
  6. ascending: Bool,
  7. fetchLimit: Int? = nil,
  8. batchSize: Int? = nil
  9. ) -> NSFetchRequest<GlucoseStored> {
  10. let request = GlucoseStored.fetchRequest()
  11. request.sortDescriptors = [NSSortDescriptor(keyPath: \GlucoseStored.date, ascending: ascending)]
  12. request.predicate = predicate
  13. if let limit = fetchLimit {
  14. request.fetchLimit = limit
  15. }
  16. if let batchSize = batchSize {
  17. request.fetchBatchSize = batchSize
  18. }
  19. return request
  20. }
  21. static func glucoseIsFlat(_ glucose: [GlucoseStored]) -> Bool {
  22. guard glucose.count >= 6 else { return false }
  23. let firstValue = glucose.first?.glucose
  24. return glucose.allSatisfy { $0.glucose == firstValue }
  25. }
  26. }
  27. extension NSPredicate {
  28. static var glucose: NSPredicate {
  29. let date = Date.oneDayAgo
  30. return NSPredicate(format: "isManual == %@ AND date >= %@", false as NSNumber, date as NSDate)
  31. }
  32. static var manualGlucose: NSPredicate {
  33. let date = Date.oneDayAgo
  34. return NSPredicate(format: "isManual == %@ AND date >= %@", true as NSNumber, date as NSDate)
  35. }
  36. static var glucoseForStatsDay: NSPredicate {
  37. let date = Date.oneDayAgo
  38. return NSPredicate(format: "date >= %@", date as NSDate)
  39. }
  40. static var glucoseForStatsToday: NSPredicate {
  41. let date = Date.startOfToday
  42. return NSPredicate(format: "date >= %@", date as NSDate)
  43. }
  44. static var glucoseForStatsMonth: NSPredicate {
  45. let date = Date.oneMonthAgo
  46. return NSPredicate(format: "date >= %@", date as NSDate)
  47. }
  48. static var glucoseForStatsTotal: NSPredicate {
  49. let date = Date.threeMonthsAgo
  50. return NSPredicate(format: "date >= %@", date as NSDate)
  51. }
  52. static var glucoseForStatsWeek: NSPredicate {
  53. let date = Date.oneWeekAgo
  54. return NSPredicate(format: "date >= %@", date as NSDate)
  55. }
  56. static var glucoseNotYetUploadedToNightscout: NSPredicate {
  57. let date = Date.oneDayAgo
  58. return NSPredicate(format: "date >= %@ AND isUploadedToNS == %@", date as NSDate, false as NSNumber)
  59. }
  60. static var manualGlucoseNotYetUploadedToNightscout: NSPredicate {
  61. let date = Date.oneDayAgo
  62. return NSPredicate(
  63. format: "date >= %@ AND isUploadedToNS == %@ AND isManual == %@",
  64. date as NSDate,
  65. false as NSNumber,
  66. true as NSNumber
  67. )
  68. }
  69. }
  70. extension GlucoseStored: Encodable {
  71. enum CodingKeys: String, CodingKey {
  72. case date
  73. case dateString
  74. case sgv
  75. case glucose
  76. case direction
  77. case id
  78. case type
  79. }
  80. public func encode(to encoder: Encoder) throws {
  81. var container = encoder.container(keyedBy: CodingKeys.self)
  82. let dateFormatter = ISO8601DateFormatter()
  83. dateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
  84. try container.encode(dateFormatter.string(from: date ?? Date()), forKey: .dateString)
  85. let dateAsUnixTimestamp = String(format: "%.0f", (date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000)
  86. try container.encode(dateAsUnixTimestamp, forKey: .date)
  87. try container.encode(direction, forKey: .direction)
  88. try container.encode(id, forKey: .id)
  89. // TODO: Handle the type of the glucose entry conditionally not hardcoded
  90. try container.encode("sgv", forKey: .type)
  91. if isManual {
  92. try container.encode(glucose, forKey: .glucose)
  93. } else {
  94. try container.encode(glucose, forKey: .sgv)
  95. }
  96. }
  97. }
  98. // In order to show the correct direction in the bobble we convert the direction property of the NSManagedObject GlucoseStored back to the Direction type
  99. extension GlucoseStored {
  100. var directionEnum: BloodGlucose.Direction? {
  101. BloodGlucose.Direction(rawValue: direction ?? "")
  102. }
  103. }