LiveActivityAttributes+Helper.swift 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import Foundation
  2. extension LiveActivityAttributes.ContentState {
  3. static func formatGlucose(_ value: Int, units: GlucoseUnits, forceSign: Bool) -> String {
  4. let formatter = NumberFormatter()
  5. formatter.numberStyle = .decimal
  6. formatter.maximumFractionDigits = 0
  7. if units == .mmolL {
  8. formatter.minimumFractionDigits = 1
  9. formatter.maximumFractionDigits = 1
  10. }
  11. if forceSign {
  12. formatter.positivePrefix = formatter.plusSign
  13. }
  14. formatter.roundingMode = .halfUp
  15. return formatter
  16. .string(from: units == .mmolL ? value.asMmolL as NSNumber : NSNumber(value: value))!
  17. }
  18. static func calculateChange(chart: [GlucoseData], units: GlucoseUnits) -> String {
  19. guard chart.count > 2 else { return "" }
  20. let lastGlucose = chart.first?.glucose ?? 0
  21. let secondLastGlucose = chart.dropFirst().first?.glucose ?? 0
  22. let delta = lastGlucose - secondLastGlucose
  23. let deltaAsDecimal = units == .mmolL ? Decimal(delta).asMmolL : Decimal(delta)
  24. let formatter = NumberFormatter()
  25. formatter.numberStyle = .decimal
  26. formatter.maximumFractionDigits = 1
  27. if units == .mmolL {
  28. formatter.minimumFractionDigits = 1
  29. formatter.maximumFractionDigits = 1
  30. }
  31. formatter.positivePrefix = " +"
  32. formatter.negativePrefix = " -"
  33. return formatter.string(from: deltaAsDecimal as NSNumber) ?? "--"
  34. }
  35. init?(
  36. new bg: GlucoseData,
  37. prev _: GlucoseData?,
  38. units: GlucoseUnits,
  39. chart: [GlucoseData],
  40. settings: FreeAPSSettings,
  41. determination: DeterminationData?,
  42. override: OverrideData?
  43. ) {
  44. let glucose = bg.glucose
  45. let formattedBG = Self.formatGlucose(Int(glucose), units: units, forceSign: false)
  46. var rotationDegrees: Double = 0.0
  47. switch bg.direction {
  48. case .doubleUp,
  49. .singleUp,
  50. .tripleUp:
  51. rotationDegrees = -90
  52. case .fortyFiveUp:
  53. rotationDegrees = -45
  54. case .flat:
  55. rotationDegrees = 0
  56. case .fortyFiveDown:
  57. rotationDegrees = 45
  58. case .doubleDown,
  59. .singleDown,
  60. .tripleDown:
  61. rotationDegrees = 90
  62. case nil,
  63. .notComputable,
  64. .rateOutOfRange:
  65. rotationDegrees = 0
  66. default:
  67. rotationDegrees = 0
  68. }
  69. let trendString = bg.direction?.symbol as? String
  70. let change = Self.calculateChange(chart: chart, units: units)
  71. let detailedState: LiveActivityAttributes.ContentAdditionalState?
  72. switch settings.lockScreenView {
  73. case .detailed:
  74. let chartBG = chart.map { Decimal($0.glucose) }
  75. let chartDate = chart.map(\.date)
  76. /// glucose limits from UI settings, not from notifications settings
  77. detailedState = LiveActivityAttributes.ContentAdditionalState(
  78. chart: chartBG,
  79. chartDate: chartDate,
  80. rotationDegrees: rotationDegrees,
  81. cob: Decimal(determination?.cob ?? 0),
  82. iob: determination?.iob ?? 0 as Decimal,
  83. unit: settings.units.rawValue,
  84. isOverrideActive: override?.isActive ?? false
  85. )
  86. case .simple:
  87. detailedState = nil
  88. }
  89. self.init(
  90. bg: formattedBG,
  91. direction: trendString,
  92. change: change,
  93. date: bg.date,
  94. highGlucose: settings.high,
  95. lowGlucose: settings.low,
  96. glucoseColorScheme: settings.glucoseColorScheme.rawValue,
  97. detailedViewState: detailedState,
  98. isInitialState: false
  99. )
  100. }
  101. }