GlucoseStored+helper.swift 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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 >= 4 else { return false }
  23. let lastThreeValues = glucose.suffix(4)
  24. let firstValue = lastThreeValues.last?.glucose
  25. return lastThreeValues.allSatisfy { $0.glucose == firstValue }
  26. }
  27. }
  28. extension NSPredicate {
  29. static var glucose: NSPredicate {
  30. let date = Date.oneDayAgo
  31. return NSPredicate(format: "isManual == %@ AND date >= %@", false as NSNumber, date as NSDate)
  32. }
  33. static var manualGlucose: NSPredicate {
  34. let date = Date.oneDayAgo
  35. return NSPredicate(format: "isManual == %@ AND date >= %@", true as NSNumber, date as NSDate)
  36. }
  37. }
  38. extension GlucoseStored: Encodable {
  39. enum CodingKeys: String, CodingKey {
  40. case date
  41. case dateString
  42. case sgv
  43. case glucose
  44. case direction
  45. case id
  46. case type
  47. }
  48. public func encode(to encoder: Encoder) throws {
  49. var container = encoder.container(keyedBy: CodingKeys.self)
  50. let dateFormatter = ISO8601DateFormatter()
  51. dateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
  52. try container.encode(dateFormatter.string(from: date ?? Date()), forKey: .dateString)
  53. let dateAsUnixTimestamp = String(format: "%.0f", (date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000)
  54. try container.encode(dateAsUnixTimestamp, forKey: .date)
  55. try container.encode(direction, forKey: .direction)
  56. try container.encode(id, forKey: .id)
  57. // TODO: Handle the type of the glucose entry conditionally not hardcoded
  58. try container.encode("sgv", forKey: .type)
  59. if isManual {
  60. try container.encode(glucose, forKey: .glucose)
  61. } else {
  62. try container.encode(glucose, forKey: .sgv)
  63. }
  64. }
  65. }