diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index 5543d4568a..1973bc68ed 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -25,6 +25,9 @@ final class DeviceDataManager: CarbStoreDelegate, DoseStoreDelegate { let logger = DiagnosticLogger() + /// Remember the launch date of the app for diagnostic reporting + fileprivate let launchDate = Date() + /// Manages all the RileyLinks let rileyLinkManager: RileyLinkDeviceManager @@ -841,7 +844,9 @@ extension DeviceDataManager: CGMManagerDelegate { extension DeviceDataManager: CustomDebugStringConvertible { var debugDescription: String { return [ + Bundle.main.localizedNameAndVersion, "## DeviceDataManager", + "launchDate: \(launchDate)", "cgm: \(cgm)", "latestPumpStatusFromMySentry: \(latestPumpStatusFromMySentry)", "pumpState: \(String(reflecting: pumpState))", diff --git a/Loop/Managers/NightscoutDataManager.swift b/Loop/Managers/NightscoutDataManager.swift index 45299bd011..9a2404819c 100644 --- a/Loop/Managers/NightscoutDataManager.swift +++ b/Loop/Managers/NightscoutDataManager.swift @@ -14,7 +14,7 @@ import InsulinKit import LoopKit import RileyLinkKit -class NightscoutDataManager { +final class NightscoutDataManager { unowned let deviceDataManager: DeviceDataManager @@ -29,10 +29,11 @@ class NightscoutDataManager { @objc func loopDataUpdated(_ note: Notification) { guard + deviceDataManager.remoteDataManager.nightscoutService.uploader != nil, let rawContext = note.userInfo?[LoopDataManager.LoopUpdateContextKey] as? LoopDataManager.LoopUpdateContext.RawValue, let context = LoopDataManager.LoopUpdateContext(rawValue: rawContext), case .tempBasal = context - else { + else { return } @@ -109,7 +110,7 @@ class NightscoutDataManager { } - func getUploaderStatus() -> UploaderStatus { + private func getUploaderStatus() -> UploaderStatus { // Gather UploaderStatus let uploaderDevice = UIDevice.current diff --git a/Loop/Managers/StatusChartManager.swift b/Loop/Managers/StatusChartManager.swift index 9e1747b9d7..b74bf2451f 100644 --- a/Loop/Managers/StatusChartManager.swift +++ b/Loop/Managers/StatusChartManager.swift @@ -52,6 +52,26 @@ final class StatusChartsManager { var panGestureRecognizer: UIPanGestureRecognizer? + func didReceiveMemoryWarning() { + xAxisValues = nil + glucosePoints = [] + predictedGlucosePoints = [] + alternatePredictedGlucosePoints = nil + targetGlucosePoints = [] + targetOverridePoints = [] + targetOverrideDurationPoints = [] + iobPoints = [] + cobPoints = [] + basalDosePoints = [] + bolusDosePoints = [] + allDosePoints = [] + + glucoseChartCache = nil + iobChartCache = nil + cobChartCache = nil + doseChartCache = nil + } + // MARK: - Data /// The earliest date on the X-axis diff --git a/Loop/Models/BolusRecommendation.swift b/Loop/Models/BolusRecommendation.swift index cc225f26ee..e72e1d3f9d 100644 --- a/Loop/Models/BolusRecommendation.swift +++ b/Loop/Models/BolusRecommendation.swift @@ -25,7 +25,7 @@ enum BolusRecommendationNotice: CustomStringConvertible, Equatable { case .currentGlucoseBelowTarget(let glucose, let unit): let glucoseFormatter = NumberFormatter.glucoseFormatter(for: unit) let bgStr = glucoseFormatter.describingGlucose(glucose.quantity, for: unit)! - return String(format: NSLocalizedString("Current glucose of %1$@ is below target range.", comment: "Message when offering bolus prediction even though bg is below range. (1: glucose value)"), bgStr) + return String(format: NSLocalizedString("Current glucose of %1$@ is below target range.", comment: "Message when offering bolus recommendation even though bg is below range. (1: glucose value)"), bgStr) case .predictedGlucoseBelowTarget(let minGlucose, let unit): let timeFormatter = DateFormatter() timeFormatter.dateStyle = .none @@ -34,7 +34,7 @@ enum BolusRecommendationNotice: CustomStringConvertible, Equatable { let glucoseFormatter = NumberFormatter.glucoseFormatter(for: unit) let minBGStr = glucoseFormatter.describingGlucose(minGlucose.quantity, for: unit)! - return String(format: NSLocalizedString("Predicted glucose at %1$@ is %2$@.", comment: "Message when offering bolus prediction even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number)"), time, minBGStr) + return String(format: NSLocalizedString("Predicted glucose at %1$@ is %2$@.", comment: "Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number)"), time, minBGStr) } } diff --git a/Loop/View Controllers/SettingsTableViewController.swift b/Loop/View Controllers/SettingsTableViewController.swift index 942c59fc4b..70df62c805 100644 --- a/Loop/View Controllers/SettingsTableViewController.swift +++ b/Loop/View Controllers/SettingsTableViewController.swift @@ -376,8 +376,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { switch Section(rawValue: section)! { case .loop: - let bundle = Bundle.main - return bundle.localizedNameAndVersion + return Bundle.main.localizedNameAndVersion case .pump: return NSLocalizedString("Pump", comment: "The title of the pump section in settings") case .cgm: diff --git a/Loop/View Controllers/StatusTableViewController.swift b/Loop/View Controllers/StatusTableViewController.swift index 0b4c057622..6d12e603a3 100644 --- a/Loop/View Controllers/StatusTableViewController.swift +++ b/Loop/View Controllers/StatusTableViewController.swift @@ -99,6 +99,15 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize } } + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + + if !visible { + charts.didReceiveMemoryWarning() + refreshContext = .all + } + } + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) @@ -215,6 +224,12 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize reloadGroup.enter() self.dataManager.loopManager.getLoopStatus { (predictedGlucose, _, recommendedTempBasal, lastTempBasal, lastLoopCompleted, _, _, _) -> Void in self.charts.setPredictedGlucoseValues(predictedGlucose ?? []) + + // Retry this refresh again if predicted glucose isn't available + if predictedGlucose == nil { + self.refreshContext.update(with: .status) + } + newRecommendedTempBasal = recommendedTempBasal self.lastTempBasal = lastTempBasal self.lastLoopCompleted = lastLoopCompleted @@ -396,13 +411,6 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize private var totalDelivery: Double? - private lazy var integerFormatter: NumberFormatter = { - let formatter = NumberFormatter() - formatter.maximumFractionDigits = 0 - - return formatter - }() - // MARK: COB private var currentCOBDescription: String? @@ -431,14 +439,6 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize } } - private lazy var timeFormatter: DateFormatter = { - let formatter = DateFormatter() - formatter.dateStyle = .none - formatter.timeStyle = .short - - return formatter - }() - // MARK: - HUD Data private var lastTempBasal: DoseEntry? { @@ -534,6 +534,10 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize switch StatusRow(rawValue: indexPath.row)! { case .recommendedBasal: if let recommendedTempBasal = recommendedTempBasal { + let timeFormatter = DateFormatter() + timeFormatter.dateStyle = .none + timeFormatter.timeStyle = .short + cell.subtitleLabel?.text = String(format: NSLocalizedString("%1$@ U/hour @ %2$@", comment: "The format for recommended temp basal rate and time. (1: localized rate number)(2: localized time)"), NumberFormatter.localizedString(from: NSNumber(value: recommendedTempBasal.rate), number: .decimal), timeFormatter.string(from: recommendedTempBasal.recommendedDate)) cell.selectionStyle = .default } else { @@ -570,6 +574,9 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize cell.subtitleLabel?.text = nil } case .dose: + let integerFormatter = NumberFormatter() + integerFormatter.maximumFractionDigits = 0 + if let total = totalDelivery, let totalString = integerFormatter.string(from: NSNumber(value: total)) { cell.subtitleLabel?.text = String(format: NSLocalizedString("%@ U Total", comment: "The subtitle format describing total insulin. (1: localized insulin total)"), totalString) @@ -727,14 +734,13 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize } } } - self.dataManager.loopManager.getLoopStatus({ (_, _, _, _, _, iob, cob, _) in + self.dataManager.loopManager.getLoopStatus { (_, _, _, _, _, iob, cob, _) in DispatchQueue.main.async { vc.glucoseUnit = self.charts.glucoseUnit vc.activeInsulin = iob?.value vc.activeCarbohydrates = cob?.quantity.doubleValue(for: HKUnit.gram()) } - }) - + } case let vc as PredictionTableViewController: vc.dataManager = dataManager case let vc as SettingsTableViewController: