LiveActivityAttributes+Helper.swift 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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(\.glucose)
  75. let conversionFactor: Double = settings.units == .mmolL ? 18.0 : 1.0
  76. let convertedChartBG = chartBG.map { Double($0) / conversionFactor }
  77. let chartDate = chart.map(\.date)
  78. /// glucose limits from UI settings, not from notifications settings
  79. let highGlucose = settings.high / Decimal(conversionFactor)
  80. let lowGlucose = settings.low / Decimal(conversionFactor)
  81. let cob = determination?.cob ?? 0
  82. let iob = determination?.iob ?? 0
  83. let unit = settings.units == .mmolL ? " mmol/L" : " mg/dL"
  84. let isOverrideActive = override?.isActive ?? false
  85. detailedState = LiveActivityAttributes.ContentAdditionalState(
  86. chart: convertedChartBG,
  87. chartDate: chartDate,
  88. rotationDegrees: rotationDegrees,
  89. highGlucose: Double(highGlucose),
  90. lowGlucose: Double(lowGlucose),
  91. dynamicBGColor: settings.dynamicBGColor,
  92. cob: Decimal(cob),
  93. iob: iob as Decimal,
  94. unit: unit,
  95. isOverrideActive: isOverrideActive
  96. )
  97. case .simple:
  98. detailedState = nil
  99. }
  100. self.init(
  101. bg: formattedBG,
  102. direction: trendString,
  103. change: change,
  104. date: bg.date,
  105. detailedViewState: detailedState,
  106. isInitialState: false
  107. )
  108. }
  109. }