diff --git a/Cartfile b/Cartfile index 66a46975b2..ca66f13586 100644 --- a/Cartfile +++ b/Cartfile @@ -1,7 +1,7 @@ github "LoopKit/LoopKit" "dev" github "LoopKit/CGMBLEKit" "dev" github "i-schuetz/SwiftCharts" == 0.6.5 -github "LoopKit/dexcom-share-client-swift" ~> 1.2 -github "LoopKit/G4ShareSpy" ~> 1.1 +github "LoopKit/dexcom-share-client-swift" "dev" +github "LoopKit/G4ShareSpy" "dev" github "ps2/rileylink_ios" "dev" github "LoopKit/Amplitude-iOS" "decreepify" diff --git a/Cartfile.resolved b/Cartfile.resolved index e22353e2b1..589cedc8a3 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,8 +1,8 @@ github "LoopKit/Amplitude-iOS" "2137d5fd44bf630ed33e1e72d7af6d8f8612f270" -github "LoopKit/CGMBLEKit" "aaa67861eeddfd6dd8b4b59e8d71cfa065fb07f8" -github "LoopKit/G4ShareSpy" "v1.1" -github "LoopKit/LoopKit" "2ea6be077000ad8300bd9afa556f34a101b8904b" +github "LoopKit/CGMBLEKit" "94742e1137aa29e26dff3457d0ab42b56a2ed121" +github "LoopKit/G4ShareSpy" "88c5a296e83ce618319ae365a7e6da76d9be126b" +github "LoopKit/LoopKit" "8bc6e4b4ed4d8a7e98d8dcf539238b98c83ed3d1" github "LoopKit/MKRingProgressView" "f548a5c64832be2d37d7c91b5800e284887a2a0a" -github "LoopKit/dexcom-share-client-swift" "v1.2" +github "LoopKit/dexcom-share-client-swift" "c37d87fcf121c44721e87c9e6d2bea94e48728cc" github "i-schuetz/SwiftCharts" "0.6.5" -github "ps2/rileylink_ios" "95429e28a54d3123a0944ec8f658ba1c636b6ef8" +github "ps2/rileylink_ios" "7406784b44d351808e83d5af604aa15b7d82b62d" diff --git a/Loop/Base.lproj/Main.storyboard b/Loop/Base.lproj/Main.storyboard index a2a8aa0101..07ba662f49 100644 --- a/Loop/Base.lproj/Main.storyboard +++ b/Loop/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -448,19 +448,19 @@ - + - + - + - + @@ -863,13 +863,13 @@ - + @@ -881,7 +881,7 @@ diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index 194382ec2b..1da92444d1 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -35,6 +35,8 @@ final class DeviceDataManager { /// The last time a BLE heartbeat was received and acted upon. private var lastBLEDrivenUpdate = Date.distantPast + + private var deviceLog: PersistentDeviceLog // MARK: - CGM @@ -86,6 +88,10 @@ final class DeviceDataManager { init() { pluginManager = PluginManager() + + let fileManager = FileManager.default + let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first! + deviceLog = PersistentDeviceLog(storageFile: documentsDirectory.appendingPathComponent("DeviceLog.sqlite")) if let pumpManagerRawValue = UserDefaults.appGroup?.pumpManagerRawValue { pumpManager = pumpManagerFromRawValue(pumpManagerRawValue) @@ -189,7 +195,51 @@ final class DeviceDataManager { updatePumpManagerBLEHeartbeatPreference() } - + func generateDiagnosticReport(_ completion: @escaping (_ report: String) -> Void) { + self.loopManager.generateDiagnosticReport { (loopReport) in + self.deviceLog.getLogEntries(startDate: Date() - .hours(48)) { (result) in + let deviceLogReport: String + switch result { + case .failure(let error): + deviceLogReport = "Error fetching entries: \(error)" + case .success(let entries): + deviceLogReport = entries.map { "* \($0.timestamp) \($0.managerIdentifier) \($0.deviceIdentifier ?? "") \($0.type) \($0.message)" }.joined(separator: "\n") + } + + let report = [ + Bundle.main.localizedNameAndVersion, + "* gitRevision: \(Bundle.main.gitRevision ?? "N/A")", + "* gitBranch: \(Bundle.main.gitBranch ?? "N/A")", + "* sourceRoot: \(Bundle.main.sourceRoot ?? "N/A")", + "* buildDateString: \(Bundle.main.buildDateString ?? "N/A")", + "* xcodeVersion: \(Bundle.main.xcodeVersion ?? "N/A")", + "", + "## FeatureFlags", + "\(FeatureFlags)", + "", + "## DeviceDataManager", + "* launchDate: \(self.launchDate)", + "* lastError: \(String(describing: self.lastError))", + "* lastBLEDrivenUpdate: \(self.lastBLEDrivenUpdate)", + "", + self.cgmManager != nil ? String(reflecting: self.cgmManager!) : "cgmManager: nil", + "", + self.pumpManager != nil ? String(reflecting: self.pumpManager!) : "pumpManager: nil", + "", + "## Device Communication Log", + deviceLogReport, + "", + String(reflecting: self.watchManager!), + "", + String(reflecting: self.statusExtensionManager!), + "", + loopReport, + ].joined(separator: "\n") + + completion(report) + } + } + } } private extension DeviceDataManager { @@ -274,6 +324,7 @@ extension DeviceDataManager: RemoteDataManagerDelegate { // MARK: - DeviceManagerDelegate extension DeviceDataManager: DeviceManagerDelegate { + func scheduleNotification(for manager: DeviceManager, identifier: String, content: UNNotificationContent, @@ -290,6 +341,10 @@ extension DeviceDataManager: DeviceManagerDelegate { func clearNotification(for manager: DeviceManager, identifier: String) { UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [identifier]) } + + func deviceManager(_ manager: DeviceManager, logEventForDeviceIdentifier deviceIdentifier: String?, type: DeviceLogEntryType, message: String, completion: ((Error?) -> Void)?) { + deviceLog.log(managerIdentifier: Swift.type(of: manager).managerIdentifier, deviceIdentifier: deviceIdentifier, type: type, message: message, completion: completion) + } } // MARK: - CGMManagerDelegate @@ -620,34 +675,6 @@ extension DeviceDataManager: LoopDataManagerDelegate { } } - -// MARK: - CustomDebugStringConvertible -extension DeviceDataManager: CustomDebugStringConvertible { - var debugDescription: String { - return [ - Bundle.main.localizedNameAndVersion, - "* gitRevision: \(Bundle.main.gitRevision ?? "N/A")", - "* gitBranch: \(Bundle.main.gitBranch ?? "N/A")", - "* sourceRoot: \(Bundle.main.sourceRoot ?? "N/A")", - "* buildDateString: \(Bundle.main.buildDateString ?? "N/A")", - "* xcodeVersion: \(Bundle.main.xcodeVersion ?? "N/A")", - "", - "## DeviceDataManager", - "* launchDate: \(launchDate)", - "* lastError: \(String(describing: lastError))", - "* lastBLEDrivenUpdate: \(lastBLEDrivenUpdate)", - "", - cgmManager != nil ? String(reflecting: cgmManager!) : "cgmManager: nil", - "", - pumpManager != nil ? String(reflecting: pumpManager!) : "pumpManager: nil", - "", - String(reflecting: watchManager!), - "", - String(reflecting: statusExtensionManager!), - ].joined(separator: "\n") - } -} - extension Notification.Name { static let PumpManagerChanged = Notification.Name(rawValue: "com.loopKit.notification.PumpManagerChanged") static let PumpEventsAdded = Notification.Name(rawValue: "com.loopKit.notification.PumpEventsAdded") diff --git a/Loop/View Controllers/BolusViewController.swift b/Loop/View Controllers/BolusViewController.swift index 8a2794a401..ba21caa0cb 100644 --- a/Loop/View Controllers/BolusViewController.swift +++ b/Loop/View Controllers/BolusViewController.swift @@ -105,6 +105,7 @@ final class BolusViewController: ChartsTableViewController, IdentifiableClass, U switch configuration { case .manualCorrection: title = NSLocalizedString("Bolus", comment: "Title text for bolus screen (manual correction)") + navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancel)) case .newCarbEntry, .updatedCarbEntry: title = NSLocalizedString("Meal Bolus", comment: "Title text for bolus screen following a carb entry") } diff --git a/Loop/View Controllers/CarbEntryViewController.swift b/Loop/View Controllers/CarbEntryViewController.swift index d96a18f18f..44801929fc 100644 --- a/Loop/View Controllers/CarbEntryViewController.swift +++ b/Loop/View Controllers/CarbEntryViewController.swift @@ -151,6 +151,9 @@ final class CarbEntryViewController: ChartsTableViewController, IdentifiableClas navigationItem.rightBarButtonItem = UIBarButtonItem(title: footerView.primaryButton.titleLabel?.text, style: .plain, target: self, action: #selector(continueButtonPressed)) navigationItem.rightBarButtonItem?.isEnabled = false + + // Sets text for back button on bolus screen + navigationItem.backBarButtonItem = UIBarButtonItem(title: NSLocalizedString("Carb Entry", comment: "Back button text for bolus screen to return to carb entry screen"), style: .plain, target: nil, action: nil) } override func viewDidAppear(_ animated: Bool) { diff --git a/Loop/View Controllers/CommandResponseViewController.swift b/Loop/View Controllers/CommandResponseViewController.swift index f6d9d3ac25..d000dfe99d 100644 --- a/Loop/View Controllers/CommandResponseViewController.swift +++ b/Loop/View Controllers/CommandResponseViewController.swift @@ -16,14 +16,12 @@ extension CommandResponseViewController { static func generateDiagnosticReport(deviceManager: DeviceDataManager) -> T { let date = Date() let vc = T(command: { (completionHandler) in - deviceManager.loopManager.generateDiagnosticReport { (report) in + deviceManager.generateDiagnosticReport { (report) in DispatchQueue.main.async { completionHandler([ "Use the Share button above save this diagnostic report to aid investigating your problem. Issues can be filed at https://github.com/LoopKit/Loop/issues.", "Generated: \(date)", "", - String(reflecting: deviceManager), - "", report, "", ].joined(separator: "\n\n"))