From 3231951eb6334837c4aad417aa70ac02d7b6f61e Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 26 Sep 2019 03:29:10 -0500 Subject: [PATCH 01/13] Allow overrides to be enabled via APNs --- Loop.xcodeproj/project.pbxproj | 8 +++-- Loop/AppDelegate.swift | 34 ++++++++++++++++++ Loop/Info.plist | 1 + Loop/Loop.entitlements | 2 ++ Loop/Managers/AnalyticsManager.swift | 4 +-- Loop/Managers/DeviceDataManager.swift | 18 ++++++++++ Loop/Managers/LoopDataManager.swift | 21 +++++++---- Loop/Managers/NightscoutDataManager.swift | 10 ++++-- Loop/Managers/NotificationManager.swift | 16 ++++++++- Loop/Models/RemoteCommand.swift | 44 +++++++++++++++++++++++ LoopCore/LoopSettings.swift | 6 +++- 11 files changed, 149 insertions(+), 15 deletions(-) create mode 100644 Loop/Models/RemoteCommand.swift diff --git a/Loop.xcodeproj/project.pbxproj b/Loop.xcodeproj/project.pbxproj index d574b0dbb0..370a7af0c5 100644 --- a/Loop.xcodeproj/project.pbxproj +++ b/Loop.xcodeproj/project.pbxproj @@ -367,6 +367,7 @@ C136AA2423109CC6008A320D /* LoopPlugins.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16DA84122E8E112008624C2 /* LoopPlugins.swift */; }; C13BAD941E8009B000050CB5 /* NumberFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43BFF0B31E45C1BE00FF19A9 /* NumberFormatter.swift */; }; C15713821DAC6983005BC4D2 /* MealBolusNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C15713811DAC6983005BC4D2 /* MealBolusNightscoutTreatment.swift */; }; + C165B8CE23302C5D0004112E /* RemoteCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C165B8CD23302C5D0004112E /* RemoteCommand.swift */; }; C16DA84222E8E112008624C2 /* LoopPlugins.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16DA84122E8E112008624C2 /* LoopPlugins.swift */; }; C178249A1E1999FA00D9D25C /* CaseCountable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17824991E1999FA00D9D25C /* CaseCountable.swift */; }; C17824A01E19CF9800D9D25C /* GlucoseThresholdTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C178249F1E19CF9800D9D25C /* GlucoseThresholdTableViewController.swift */; }; @@ -1016,6 +1017,7 @@ C12CB9B823106A6300F84978 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Intents.strings; sourceTree = ""; }; C12F21A61DFA79CB00748193 /* recommend_temp_basal_very_low_end_in_range.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = recommend_temp_basal_very_low_end_in_range.json; sourceTree = ""; }; C15713811DAC6983005BC4D2 /* MealBolusNightscoutTreatment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MealBolusNightscoutTreatment.swift; sourceTree = ""; }; + C165B8CD23302C5D0004112E /* RemoteCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteCommand.swift; sourceTree = ""; }; C16DA84122E8E112008624C2 /* LoopPlugins.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopPlugins.swift; sourceTree = ""; }; C17824991E1999FA00D9D25C /* CaseCountable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaseCountable.swift; sourceTree = ""; }; C178249F1E19CF9800D9D25C /* GlucoseThresholdTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlucoseThresholdTableViewController.swift; sourceTree = ""; }; @@ -1229,6 +1231,7 @@ 438D42F81D7C88BC003244B0 /* PredictionInputEffect.swift */, 43441A9B1EDB34810087958C /* StatusExtensionContext+LoopKit.swift */, 4328E0311CFC068900E199AA /* WatchContext+LoopKit.swift */, + C165B8CD23302C5D0004112E /* RemoteCommand.swift */, ); path = Models; sourceTree = ""; @@ -2591,6 +2594,7 @@ 434FF1EE1CF27EEF000DB779 /* UITableViewCell.swift in Sources */, 439BED2A1E76093C00B0AED5 /* CGMManager.swift in Sources */, C18C8C511D5A351900E043FB /* NightscoutDataManager.swift in Sources */, + C165B8CE23302C5D0004112E /* RemoteCommand.swift in Sources */, 438849EA1D297CB6003B3F23 /* NightscoutService.swift in Sources */, 438172D91F4E9E37003C3328 /* NewPumpEvent.swift in Sources */, 4389916B1E91B689000EEF90 /* ChartSettings+Loop.swift in Sources */, @@ -3626,7 +3630,7 @@ CODE_SIGN_ENTITLEMENTS = Learn/Learn.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = UY678SP37Q; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Learn/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; @@ -3654,7 +3658,7 @@ CODE_SIGN_ENTITLEMENTS = Learn/Learn.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = UY678SP37Q; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Learn/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; diff --git a/Loop/AppDelegate.swift b/Loop/AppDelegate.swift index ed8d9e6333..906fff9a52 100644 --- a/Loop/AppDelegate.swift +++ b/Loop/AppDelegate.swift @@ -32,6 +32,12 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { AnalyticsManager.shared.application(application, didFinishLaunchingWithOptions: launchOptions) rootViewController.rootViewController.deviceManager = deviceManager + + let notificationOption = launchOptions?[.remoteNotification] + + if let notification = notificationOption as? [String: AnyObject] { + deviceManager.handleRemoteNotification(notification) + } return true } @@ -74,6 +80,33 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { return false } } + + // MARK: - Remote notifications + func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { + let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) } + let token = tokenParts.joined() + print("Device Token: \(token)") + print("bundle id: \(String(describing: Bundle.main.bundleIdentifier))") + deviceManager.loopManager.settings.deviceToken = deviceToken + } + + func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { + print("Failed to register: \(error)") + } + + func application(_ application: UIApplication, + didReceiveRemoteNotification userInfo: [AnyHashable : Any], + fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void + ) { + guard let notification = userInfo as? [String: AnyObject] else { + completionHandler(.failed) + return + } + + deviceManager.handleRemoteNotification(notification) + completionHandler(.noData) + } + } @@ -102,4 +135,5 @@ extension AppDelegate: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.badge, .sound, .alert]) } + } diff --git a/Loop/Info.plist b/Loop/Info.plist index 7c55571e92..f8907e07d0 100644 --- a/Loop/Info.plist +++ b/Loop/Info.plist @@ -62,6 +62,7 @@ UIBackgroundModes bluetooth-central + remote-notification UILaunchStoryboardName LaunchScreen diff --git a/Loop/Loop.entitlements b/Loop/Loop.entitlements index d590778126..a6fd580f0b 100644 --- a/Loop/Loop.entitlements +++ b/Loop/Loop.entitlements @@ -2,6 +2,8 @@ + aps-environment + development com.apple.developer.healthkit com.apple.developer.healthkit.access diff --git a/Loop/Managers/AnalyticsManager.swift b/Loop/Managers/AnalyticsManager.swift index 5dca68162f..78d94d8966 100644 --- a/Loop/Managers/AnalyticsManager.swift +++ b/Loop/Managers/AnalyticsManager.swift @@ -150,8 +150,8 @@ final class AnalyticsManager: IdentifiableClass { logEvent("CGM Fetch", outOfSession: true) } - func loopDidSucceed() { - logEvent("Loop success", outOfSession: true) + func loopDidSucceed(_ duration: TimeInterval) { + logEvent("Loop success", withProperties: ["duration": duration], outOfSession: true) } func loopDidError() { diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index ca332379b1..bee876788e 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -647,3 +647,21 @@ extension Notification.Name { static let PumpEventsAdded = Notification.Name(rawValue: "com.loopKit.notification.PumpEventsAdded") } +// MARK: - Remote Notification Handling +extension DeviceDataManager { + func handleRemoteNotification(_ aps: [String: AnyObject]) { + + if let command = RemoteCommand(aps: aps, allowedPresets: loopManager.settings.overridePresets) { + switch command { + case .temporaryScheduleOverride(let override): + log.default("Enacting remote temporary override: \(override)") + loopManager.settings.scheduleOverride = override + case .cancelTemporaryOverride: + log.default("Canceling temporary override from remote command") + loopManager.settings.scheduleOverride = nil + } + } else { + log.info("Unhandled remote notification: \(aps)") + } + } +} diff --git a/Loop/Managers/LoopDataManager.swift b/Loop/Managers/LoopDataManager.swift index a7f02eaae9..aac8e72500 100644 --- a/Loop/Managers/LoopDataManager.swift +++ b/Loop/Managers/LoopDataManager.swift @@ -216,6 +216,8 @@ final class LoopDataManager { private let lockedBasalDeliveryState: Locked fileprivate var lastRequestedBolus: DoseEntry? + + private var lastLoopStarted: Date? /// The last date at which a loop completed, from prediction to dose (if dosing is enabled) var lastLoopCompleted: Date? { @@ -224,11 +226,6 @@ final class LoopDataManager { } set { lockedLastLoopCompleted.value = newValue - - NotificationManager.clearLoopNotRunningNotifications() - NotificationManager.scheduleLoopNotRunningNotifications() - AnalyticsManager.shared.loopDidSucceed() - NotificationCenter.default.post(name: .LoopCompleted, object: self) } } private let lockedLastLoopCompleted: Locked @@ -269,6 +266,15 @@ final class LoopDataManager { backgroundTask = .invalid } } + + private func loopDidComplete(date: Date, duration: TimeInterval) { + lastLoopCompleted = date + NotificationManager.clearLoopNotRunningNotifications() + NotificationManager.scheduleLoopNotRunningNotifications() + AnalyticsManager.shared.loopDidSucceed(duration) + NotificationCenter.default.post(name: .LoopCompleted, object: self) + + } } // MARK: Background task management @@ -635,6 +641,7 @@ extension LoopDataManager { NotificationCenter.default.post(name: .LoopRunning, object: self) self.lastLoopError = nil + let startDate = Date() do { try self.update() @@ -646,7 +653,7 @@ extension LoopDataManager { if let error = error { self.logger.error(error) } else { - self.lastLoopCompleted = Date() + self.loopDidComplete(date: Date(), duration: -startDate.timeIntervalSinceNow) } self.logger.default("Loop ended") self.notify(forChange: .tempBasal) @@ -655,7 +662,7 @@ extension LoopDataManager { // Delay the notification until we know the result of the temp basal return } else { - self.lastLoopCompleted = Date() + self.loopDidComplete(date: Date(), duration: -startDate.timeIntervalSinceNow) } } catch let error { self.lastLoopError = error diff --git a/Loop/Managers/NightscoutDataManager.swift b/Loop/Managers/NightscoutDataManager.swift index 320f1a174a..3285abf693 100644 --- a/Loop/Managers/NightscoutDataManager.swift +++ b/Loop/Managers/NightscoutDataManager.swift @@ -50,9 +50,10 @@ final class NightscoutDataManager { } private func uploadSettings() { + let settings = deviceManager.loopManager.settings + guard let uploader = deviceManager.remoteDataManager.nightscoutService.uploader, - let settings = UserDefaults.appGroup?.loopSettings, let basalRateSchedule = UserDefaults.appGroup?.basalRateSchedule, let insulinModelSettings = UserDefaults.appGroup?.insulinModelSettings, let carbRatioSchedule = UserDefaults.appGroup?.carbRatioSchedule, @@ -63,6 +64,9 @@ final class NightscoutDataManager { log.default("Not uploading due to incomplete configuration") return } + + + print("******************* Upload settings ****************") let targetLowItems = correctionSchedule.items.map { (item) -> ProfileSet.ScheduleItem in return ProfileSet.ScheduleItem(offset: item.startTime, value: item.value.minValue) @@ -90,7 +94,9 @@ final class NightscoutDataManager { minimumBGGuard: settings.suspendThreshold?.quantity.doubleValue(for: preferredUnit), preMealTargetRange: nsPreMealTargetRange, maximumBasalRatePerHour: settings.maximumBasalRatePerHour, - maximumBolus: settings.maximumBolus) + maximumBolus: settings.maximumBolus, + deviceToken: settings.deviceToken, + bundleIdentifier: Bundle.main.bundleIdentifier) let profile = ProfileSet.Profile( timezone: basalRateSchedule.timeZone, diff --git a/Loop/Managers/NotificationManager.swift b/Loop/Managers/NotificationManager.swift index 8f93f322ec..9320766f94 100644 --- a/Loop/Managers/NotificationManager.swift +++ b/Loop/Managers/NotificationManager.swift @@ -44,9 +44,21 @@ struct NotificationManager { let center = UNUserNotificationCenter.current() center.delegate = delegate - center.requestAuthorization(options: [.badge, .sound, .alert], completionHandler: { _, _ in }) + center.requestAuthorization(options: [.badge, .sound, .alert]) { (granted, error) in + print("Permission granted: \(granted)") + guard granted else { return } + UNUserNotificationCenter.current().getNotificationSettings { settings in + print("Notification settings: \(settings)") + guard settings.authorizationStatus == .authorized else { return } + DispatchQueue.main.async { + print("Registering for remote notifications") + UIApplication.shared.registerForRemoteNotifications() + } + } + } center.setNotificationCategories(notificationCategories) } + // MARK: - Notifications @@ -226,4 +238,6 @@ struct NotificationManager { static func clearPumpReservoirNotification() { UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [LoopNotificationCategory.pumpReservoirLow.rawValue]) } + + // Push Notifications } diff --git a/Loop/Models/RemoteCommand.swift b/Loop/Models/RemoteCommand.swift new file mode 100644 index 0000000000..2ef6e36452 --- /dev/null +++ b/Loop/Models/RemoteCommand.swift @@ -0,0 +1,44 @@ +// +// RemoteCommand.swift +// Loop +// +// Created by Pete Schwamb on 9/16/19. +// Copyright © 2019 LoopKit Authors. All rights reserved. +// + +import Foundation +import LoopKit + +public enum RemoteCommandError: Error { + case expired +} + + +enum RemoteCommand { + typealias RawValue = [String: Any] + + case temporaryScheduleOverride(TemporaryScheduleOverride) + case cancelTemporaryOverride +} + + +// Push Notifications +extension RemoteCommand { + init?(aps: [String: Any], allowedPresets: [TemporaryScheduleOverridePreset]) { + if let overrideEnactName = aps["override-name"] as? String, + let preset = allowedPresets.first(where: { $0.name == overrideEnactName }) + { + let start = Date() + var override = preset.createOverride(beginningAt: start) + if let overrideDurationMinutes = aps["override-duration-minutes"] as? Double { + override.duration = .finite(TimeInterval(minutes: overrideDurationMinutes)) + } + self = .temporaryScheduleOverride(override) + } else if let _ = aps["cancel-temporary-override"] as? String { + self = .cancelTemporaryOverride + } + else { + return nil + } + } +} diff --git a/LoopCore/LoopSettings.swift b/LoopCore/LoopSettings.swift index f967be355a..fb46f48590 100644 --- a/LoopCore/LoopSettings.swift +++ b/LoopCore/LoopSettings.swift @@ -50,7 +50,11 @@ public struct LoopSettings: Equatable { public var glucoseUnit: HKUnit? { return glucoseTargetRangeSchedule?.unit } - + + // MARK - Push Notifications + + public var deviceToken: Data? + // MARK - Guardrails public func allowedSensitivityValues(for unit: HKUnit) -> [Double] { From bdbb2594167534ccb52b6595d735f855d3bff29d Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 26 Sep 2019 20:10:14 -0500 Subject: [PATCH 02/13] Update to NS sent notifications --- Cartfile | 2 +- Cartfile.resolved | 2 +- Loop.xcodeproj/project.pbxproj | 4 ++-- Loop/AppDelegate.swift | 2 +- Loop/Managers/DeviceDataManager.swift | 6 +++--- Loop/Models/RemoteCommand.swift | 8 ++++---- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cartfile b/Cartfile index ca66f13586..e8249afbf2 100644 --- a/Cartfile +++ b/Cartfile @@ -3,5 +3,5 @@ github "LoopKit/CGMBLEKit" "dev" github "i-schuetz/SwiftCharts" == 0.6.5 github "LoopKit/dexcom-share-client-swift" "dev" github "LoopKit/G4ShareSpy" "dev" -github "ps2/rileylink_ios" "dev" +github "ps2/rileylink_ios" "remote-overrides" github "LoopKit/Amplitude-iOS" "decreepify" diff --git a/Cartfile.resolved b/Cartfile.resolved index c07a8ca0f6..2627489834 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -5,4 +5,4 @@ github "LoopKit/LoopKit" "18a5a04afd310e945ac54f8c43a44838a16503c2" github "LoopKit/MKRingProgressView" "f548a5c64832be2d37d7c91b5800e284887a2a0a" github "LoopKit/dexcom-share-client-swift" "c4f3d48e56e5b3ad786486ccd1bbc753034096d2" github "i-schuetz/SwiftCharts" "0.6.5" -github "ps2/rileylink_ios" "4e37d82e45f87d239bbd160ceacb5eca50d0336e" +github "ps2/rileylink_ios" "d3053f027d3e1d738946f0f912ea6db68c2a5fd1" diff --git a/Loop.xcodeproj/project.pbxproj b/Loop.xcodeproj/project.pbxproj index 370a7af0c5..86002b013e 100644 --- a/Loop.xcodeproj/project.pbxproj +++ b/Loop.xcodeproj/project.pbxproj @@ -3630,7 +3630,7 @@ CODE_SIGN_ENTITLEMENTS = Learn/Learn.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = UY678SP37Q; + DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Learn/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; @@ -3658,7 +3658,7 @@ CODE_SIGN_ENTITLEMENTS = Learn/Learn.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = UY678SP37Q; + DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Learn/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; diff --git a/Loop/AppDelegate.swift b/Loop/AppDelegate.swift index 906fff9a52..ea7cd6b486 100644 --- a/Loop/AppDelegate.swift +++ b/Loop/AppDelegate.swift @@ -26,7 +26,7 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { NotificationManager.authorize(delegate: self) - + log.info(#function) AnalyticsManager.shared.application(application, didFinishLaunchingWithOptions: launchOptions) diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index bee876788e..d40667e890 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -649,9 +649,9 @@ extension Notification.Name { // MARK: - Remote Notification Handling extension DeviceDataManager { - func handleRemoteNotification(_ aps: [String: AnyObject]) { + func handleRemoteNotification(_ notification: [String: AnyObject]) { - if let command = RemoteCommand(aps: aps, allowedPresets: loopManager.settings.overridePresets) { + if let command = RemoteCommand(notification: notification, allowedPresets: loopManager.settings.overridePresets) { switch command { case .temporaryScheduleOverride(let override): log.default("Enacting remote temporary override: \(override)") @@ -661,7 +661,7 @@ extension DeviceDataManager { loopManager.settings.scheduleOverride = nil } } else { - log.info("Unhandled remote notification: \(aps)") + log.info("Unhandled remote notification: \(notification)") } } } diff --git a/Loop/Models/RemoteCommand.swift b/Loop/Models/RemoteCommand.swift index 2ef6e36452..9d124afbf4 100644 --- a/Loop/Models/RemoteCommand.swift +++ b/Loop/Models/RemoteCommand.swift @@ -24,17 +24,17 @@ enum RemoteCommand { // Push Notifications extension RemoteCommand { - init?(aps: [String: Any], allowedPresets: [TemporaryScheduleOverridePreset]) { - if let overrideEnactName = aps["override-name"] as? String, + init?(notification: [String: Any], allowedPresets: [TemporaryScheduleOverridePreset]) { + if let overrideEnactName = notification["override-name"] as? String, let preset = allowedPresets.first(where: { $0.name == overrideEnactName }) { let start = Date() var override = preset.createOverride(beginningAt: start) - if let overrideDurationMinutes = aps["override-duration-minutes"] as? Double { + if let overrideDurationMinutes = notification["override-duration-minutes"] as? Double { override.duration = .finite(TimeInterval(minutes: overrideDurationMinutes)) } self = .temporaryScheduleOverride(override) - } else if let _ = aps["cancel-temporary-override"] as? String { + } else if let _ = notification["cancel-temporary-override"] as? String { self = .cancelTemporaryOverride } else { From f8e03cc296795f64ef5b28d6dd8efc1ee402a8e3 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 26 Sep 2019 20:13:46 -0500 Subject: [PATCH 03/13] Cleanup prints --- Loop/AppDelegate.swift | 4 +--- Loop/Managers/NightscoutDataManager.swift | 3 --- Loop/Managers/NotificationManager.swift | 3 --- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/Loop/AppDelegate.swift b/Loop/AppDelegate.swift index ea7cd6b486..1b3ca3bf48 100644 --- a/Loop/AppDelegate.swift +++ b/Loop/AppDelegate.swift @@ -85,13 +85,11 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) } let token = tokenParts.joined() - print("Device Token: \(token)") - print("bundle id: \(String(describing: Bundle.main.bundleIdentifier))") deviceManager.loopManager.settings.deviceToken = deviceToken } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { - print("Failed to register: \(error)") + log.error("Failed to register: \(error)") } func application(_ application: UIApplication, diff --git a/Loop/Managers/NightscoutDataManager.swift b/Loop/Managers/NightscoutDataManager.swift index 3285abf693..4249f0d545 100644 --- a/Loop/Managers/NightscoutDataManager.swift +++ b/Loop/Managers/NightscoutDataManager.swift @@ -65,9 +65,6 @@ final class NightscoutDataManager { return } - - print("******************* Upload settings ****************") - let targetLowItems = correctionSchedule.items.map { (item) -> ProfileSet.ScheduleItem in return ProfileSet.ScheduleItem(offset: item.startTime, value: item.value.minValue) } diff --git a/Loop/Managers/NotificationManager.swift b/Loop/Managers/NotificationManager.swift index 9320766f94..fa08bfc4ad 100644 --- a/Loop/Managers/NotificationManager.swift +++ b/Loop/Managers/NotificationManager.swift @@ -45,13 +45,10 @@ struct NotificationManager { center.delegate = delegate center.requestAuthorization(options: [.badge, .sound, .alert]) { (granted, error) in - print("Permission granted: \(granted)") guard granted else { return } UNUserNotificationCenter.current().getNotificationSettings { settings in - print("Notification settings: \(settings)") guard settings.authorizationStatus == .authorized else { return } DispatchQueue.main.async { - print("Registering for remote notifications") UIApplication.shared.registerForRemoteNotifications() } } From 5795f015e3b166ac08327767211cab3cc21cef48 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 30 Sep 2019 14:33:28 -0500 Subject: [PATCH 04/13] Query override history for NS upload --- Loop/Managers/NightscoutDataManager.swift | 92 ++++++++++++++++--- Loop/Models/RemoteCommand.swift | 6 +- LoopCore/LoopSettings.swift | 8 +- .../Controllers/ActionHUDController.swift | 2 +- .../Scenes/GlucoseChartScene.swift | 9 +- 5 files changed, 99 insertions(+), 18 deletions(-) diff --git a/Loop/Managers/NightscoutDataManager.swift b/Loop/Managers/NightscoutDataManager.swift index 4249f0d545..bd39585038 100644 --- a/Loop/Managers/NightscoutDataManager.swift +++ b/Loop/Managers/NightscoutDataManager.swift @@ -27,6 +27,9 @@ final class NightscoutDataManager { // Last time settings were updated var lastSettingsUpdate: Date = .distantPast + + // Override history query anchor + var overrideHistoryQueryAnchor: TemporaryScheduleOverrideHistory.QueryAnchor? init(deviceDataManager: DeviceDataManager) { self.deviceManager = deviceDataManager @@ -129,6 +132,31 @@ final class NightscoutDataManager { } } } + + // Upload overrides + let (overrides, deletedOverrides, newAnchor) = deviceManager.loopManager.overrideHistory.queryByAnchor(overrideHistoryQueryAnchor) + + let updates = overrides.map { OverrideTreatment(override: $0) } + + let deletions = deletedOverrides.map { $0.syncIdentifier.uuidString } + uploader.deleteTreatmentsByClientId(deletions, completionHandler: { (error) in + if let error = error { + self.log.error("Overrides deletions failed to delete %{public}@: %{public}@", String(describing: deletions), String(describing: error)) + } else { + self.log.debug("Deleted ids: %@", deletions) + } + }) + uploader.upload(updates) { (result) in + switch result { + case .failure(let error): + self.log.error("Failed to upload overrides %{public}@: %{public}@", String(describing: updates.map {$0.dictionaryRepresentation}), String(describing: error)) + case .success: + // Should join this result with deletion result before updating anchor + self.log.error("Uploaded overrides %{public}@", String(describing: updates.map {$0.dictionaryRepresentation})) + self.overrideHistoryQueryAnchor = newAnchor + } + } + } @objc func loopCompleted(_ note: Notification) { @@ -284,8 +312,8 @@ final class NightscoutDataManager { } else { pumpStatus = nil } + //add overrideStatus - let overrideStatus: NightscoutUploadKit.OverrideStatus? let settings = deviceManager.loopManager.settings let unit: HKUnit = settings.glucoseTargetRangeSchedule?.unit ?? HKUnit.milligramsPerDeciliter @@ -413,15 +441,16 @@ private extension Array where Element == RepeatingScheduleValue { } } +// Likely this will be deprecated, in favor of override history uploading to NS treatments private extension LoopKit.TemporaryScheduleOverride { func nsScheduleOverride(for unit: HKUnit) -> NightscoutUploadKit.TemporaryScheduleOverride { - let nsTargetRange: ClosedRange? + let nsCorrectionRange: ClosedRange? if let targetRange = settings.targetRange { - nsTargetRange = ClosedRange(uncheckedBounds: ( + nsCorrectionRange = ClosedRange(uncheckedBounds: ( lower: targetRange.lowerBound.doubleValue(for: unit), upper: targetRange.upperBound.doubleValue(for: unit))) } else { - nsTargetRange = nil + nsCorrectionRange = nil } let nsDuration: TimeInterval @@ -451,23 +480,23 @@ private extension LoopKit.TemporaryScheduleOverride { } return NightscoutUploadKit.TemporaryScheduleOverride( - targetRange: nsTargetRange, + duration: nsDuration, + targetRange: nsCorrectionRange, insulinNeedsScaleFactor: settings.insulinNeedsScaleFactor, symbol: symbol, - duration: nsDuration, name: name) } } private extension LoopKit.TemporaryScheduleOverridePreset { func nsScheduleOverride(for unit: HKUnit) -> NightscoutUploadKit.TemporaryScheduleOverride { - let nsTargetRange: ClosedRange? + let nsCorrectionRange: ClosedRange? if let targetRange = settings.targetRange { - nsTargetRange = ClosedRange(uncheckedBounds: ( + nsCorrectionRange = ClosedRange(uncheckedBounds: ( lower: targetRange.lowerBound.doubleValue(for: unit), upper: targetRange.upperBound.doubleValue(for: unit))) } else { - nsTargetRange = nil + nsCorrectionRange = nil } let nsDuration: TimeInterval @@ -479,10 +508,51 @@ private extension LoopKit.TemporaryScheduleOverridePreset { } return NightscoutUploadKit.TemporaryScheduleOverride( - targetRange: nsTargetRange, + duration: nsDuration, + targetRange: nsCorrectionRange, insulinNeedsScaleFactor: settings.insulinNeedsScaleFactor, symbol: self.symbol, - duration: nsDuration, name: self.name) } } + +private extension OverrideTreatment { + convenience init(override: LoopKit.TemporaryScheduleOverride) { + + // NS Treatments should be in mg/dL + let unit: HKUnit = .milligramsPerDeciliter + + let nsTargetRange: ClosedRange? + if let targetRange = override.settings.targetRange { + nsTargetRange = ClosedRange(uncheckedBounds: ( + lower: targetRange.lowerBound.doubleValue(for: unit), + upper: targetRange.upperBound.doubleValue(for: unit))) + } else { + nsTargetRange = nil + } + + let reason: String + switch override.context { + case .custom: + reason = NSLocalizedString("Custom Override", comment: "Name of custom override") + case .legacyWorkout: + reason = NSLocalizedString("Workout", comment: "Name of legacy workout override") + case .preMeal: + reason = NSLocalizedString("Pre-Meal", comment: "Name of pre-meal workout override") + case .preset(let preset): + reason = preset.symbol + " " + preset.name + } + + let remoteAddress: String? + let enteredBy: String + if case .remote(let address) = override.enactTrigger { + remoteAddress = address + enteredBy = "Loop (via remote command)" + } else { + remoteAddress = nil + enteredBy = "Loop" + } + + self.init(startDate: override.startDate, enderedBy: enteredBy, reason: reason, duration: override.duration.timeInterval, correctionRange: nsTargetRange, insulinNeedsScaleFactor: override.settings.insulinNeedsScaleFactor, remoteAddress:remoteAddress, id: override.syncIdentifier.uuidString) + } +} diff --git a/Loop/Models/RemoteCommand.swift b/Loop/Models/RemoteCommand.swift index 9d124afbf4..20a80b166f 100644 --- a/Loop/Models/RemoteCommand.swift +++ b/Loop/Models/RemoteCommand.swift @@ -26,10 +26,10 @@ enum RemoteCommand { extension RemoteCommand { init?(notification: [String: Any], allowedPresets: [TemporaryScheduleOverridePreset]) { if let overrideEnactName = notification["override-name"] as? String, - let preset = allowedPresets.first(where: { $0.name == overrideEnactName }) + let preset = allowedPresets.first(where: { $0.name == overrideEnactName }), + let remoteAddress = notification["remote-address"] as? String { - let start = Date() - var override = preset.createOverride(beginningAt: start) + var override = preset.createOverride(enactTrigger: .remote(remoteAddress)) if let overrideDurationMinutes = notification["override-duration-minutes"] as? Double { override.duration = .finite(TimeInterval(minutes: overrideDurationMinutes)) } diff --git a/LoopCore/LoopSettings.swift b/LoopCore/LoopSettings.swift index fb46f48590..a62918c41b 100644 --- a/LoopCore/LoopSettings.swift +++ b/LoopCore/LoopSettings.swift @@ -136,7 +136,9 @@ extension LoopSettings { context: .preMeal, settings: TemporaryScheduleOverrideSettings(unit: unit, targetRange: premealTargetRange), startDate: date, - duration: .finite(duration) + duration: .finite(duration), + enactTrigger: .local, + syncIdentifier: UUID() ) } @@ -152,7 +154,9 @@ extension LoopSettings { context: .legacyWorkout, settings: TemporaryScheduleOverrideSettings(unit: unit, targetRange: legacyWorkoutTargetRange), startDate: date, - duration: duration.isInfinite ? .indefinite : .finite(duration) + duration: duration.isInfinite ? .indefinite : .finite(duration), + enactTrigger: .local, + syncIdentifier: UUID() ) } diff --git a/WatchApp Extension/Controllers/ActionHUDController.swift b/WatchApp Extension/Controllers/ActionHUDController.swift index 5dc6e3b496..039886722e 100644 --- a/WatchApp Extension/Controllers/ActionHUDController.swift +++ b/WatchApp Extension/Controllers/ActionHUDController.swift @@ -164,7 +164,7 @@ final class ActionHUDController: HUDInterfaceController { extension ActionHUDController: OverrideSelectionControllerDelegate { func overrideSelectionController(_ controller: OverrideSelectionController, didSelectPreset preset: TemporaryScheduleOverridePreset) { - let override = preset.createOverride() + let override = preset.createOverride(enactTrigger: .local) sendOverride(override) } } diff --git a/WatchApp Extension/Scenes/GlucoseChartScene.swift b/WatchApp Extension/Scenes/GlucoseChartScene.swift index 0188ab6d75..c9b8315a99 100644 --- a/WatchApp Extension/Scenes/GlucoseChartScene.swift +++ b/WatchApp Extension/Scenes/GlucoseChartScene.swift @@ -259,7 +259,14 @@ class GlucoseChartScene: SKScene { if rangeHashable.end < spannedInterval.end { let extendedDuration = spannedInterval.end.timeIntervalSince(rangeHashable.start) - let extendedRange = TemporaryScheduleOverride(context: rangeHashable.override.context, settings: rangeHashable.override.settings, startDate: rangeHashable.start, duration: .finite(extendedDuration)) + let extendedRange = TemporaryScheduleOverride( + context: rangeHashable.override.context, + settings: rangeHashable.override.settings, + startDate: rangeHashable.start, + duration: .finite(extendedDuration), + enactTrigger: .local, + syncIdentifier: UUID() + ) let extendedRangeHashable = TemporaryScheduleOverrideHashable(extendedRange)! // Target range already known to be non-nil let (sprite2, created) = getSprite(forHash: extendedRangeHashable.chartHashValue) sprite2.color = UIColor.glucose.withAlphaComponent(0.25) From 9bb80494e4daac17398fbfd3e23d0f957b15ab2a Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 30 Sep 2019 23:16:07 -0500 Subject: [PATCH 05/13] Bump submodule revs --- Cartfile | 8 ++++---- Cartfile.resolved | 10 +++++----- Loop/Managers/NotificationManager.swift | 2 -- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Cartfile b/Cartfile index e8249afbf2..e943f98c6f 100644 --- a/Cartfile +++ b/Cartfile @@ -1,7 +1,7 @@ -github "LoopKit/LoopKit" "dev" -github "LoopKit/CGMBLEKit" "dev" +github "LoopKit/LoopKit" "remote-overrides" +github "LoopKit/CGMBLEKit" "remote-overrides" github "i-schuetz/SwiftCharts" == 0.6.5 -github "LoopKit/dexcom-share-client-swift" "dev" -github "LoopKit/G4ShareSpy" "dev" +github "LoopKit/dexcom-share-client-swift" "remote-overrides" +github "LoopKit/G4ShareSpy" "remote-overrides" github "ps2/rileylink_ios" "remote-overrides" github "LoopKit/Amplitude-iOS" "decreepify" diff --git a/Cartfile.resolved b/Cartfile.resolved index 0780e903e5..a24f5681de 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,8 +1,8 @@ github "LoopKit/Amplitude-iOS" "2137d5fd44bf630ed33e1e72d7af6d8f8612f270" -github "LoopKit/CGMBLEKit" "7417605dd898bf89378171941126c85d85dc642c" -github "LoopKit/G4ShareSpy" "e62d296067180c6659166272ff9cc406f470ec9e" -github "LoopKit/LoopKit" "18a5a04afd310e945ac54f8c43a44838a16503c2" +github "LoopKit/CGMBLEKit" "0a368795c9c29c0dba4ec0b03a7e91cd36971155" +github "LoopKit/G4ShareSpy" "27edd94e82bbef90bb67cbcee96e4a8f2f02dfbc" +github "LoopKit/LoopKit" "9e480868330d66f4b781b9c1a4e6c434de070760" github "LoopKit/MKRingProgressView" "f548a5c64832be2d37d7c91b5800e284887a2a0a" -github "LoopKit/dexcom-share-client-swift" "c4f3d48e56e5b3ad786486ccd1bbc753034096d2" +github "LoopKit/dexcom-share-client-swift" "45b8908a04a60f2cba6ac07436c661cd0ee9a39c" github "i-schuetz/SwiftCharts" "0.6.5" -github "ps2/rileylink_ios" "4bd84e45f24ae97f50f701443f056439615f5080" +github "ps2/rileylink_ios" "4dfa9dd2c6f6ba0265a76c460727ea4ed75a7dbe" diff --git a/Loop/Managers/NotificationManager.swift b/Loop/Managers/NotificationManager.swift index fa08bfc4ad..967be1cb1d 100644 --- a/Loop/Managers/NotificationManager.swift +++ b/Loop/Managers/NotificationManager.swift @@ -235,6 +235,4 @@ struct NotificationManager { static func clearPumpReservoirNotification() { UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [LoopNotificationCategory.pumpReservoirLow.rawValue]) } - - // Push Notifications } From b5a6258200f4a88ecc32f0dda4953a63fab8934d Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 1 Oct 2019 01:35:55 -0500 Subject: [PATCH 06/13] Handle indefinite duration override treatment uploads --- Loop/Managers/NightscoutDataManager.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Loop/Managers/NightscoutDataManager.swift b/Loop/Managers/NightscoutDataManager.swift index bd39585038..d3621585af 100644 --- a/Loop/Managers/NightscoutDataManager.swift +++ b/Loop/Managers/NightscoutDataManager.swift @@ -553,6 +553,13 @@ private extension OverrideTreatment { enteredBy = "Loop" } - self.init(startDate: override.startDate, enderedBy: enteredBy, reason: reason, duration: override.duration.timeInterval, correctionRange: nsTargetRange, insulinNeedsScaleFactor: override.settings.insulinNeedsScaleFactor, remoteAddress:remoteAddress, id: override.syncIdentifier.uuidString) + let duration: TimeInterval + if case .indefinite = override.duration { + duration = 0 + } else { + duration = override.duration.timeInterval + } + + self.init(startDate: override.startDate, enderedBy: enteredBy, reason: reason, duration: duration, correctionRange: nsTargetRange, insulinNeedsScaleFactor: override.settings.insulinNeedsScaleFactor, remoteAddress:remoteAddress, id: override.syncIdentifier.uuidString) } } From 7e6a007b9b6f867a56cb6ccda995955df2285992 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 6 Oct 2019 16:21:36 -0500 Subject: [PATCH 07/13] Use separate representation for indefinite duration treatments --- Loop/Managers/NightscoutDataManager.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Loop/Managers/NightscoutDataManager.swift b/Loop/Managers/NightscoutDataManager.swift index d3621585af..70689f150c 100644 --- a/Loop/Managers/NightscoutDataManager.swift +++ b/Loop/Managers/NightscoutDataManager.swift @@ -553,11 +553,12 @@ private extension OverrideTreatment { enteredBy = "Loop" } - let duration: TimeInterval - if case .indefinite = override.duration { - duration = 0 - } else { - duration = override.duration.timeInterval + let duration: OverrideTreatment.Duration + switch override.duration { + case .finite(let time): + duration = .finite(time) + case .indefinite: + duration = .indefinite } self.init(startDate: override.startDate, enderedBy: enteredBy, reason: reason, duration: duration, correctionRange: nsTargetRange, insulinNeedsScaleFactor: override.settings.insulinNeedsScaleFactor, remoteAddress:remoteAddress, id: override.syncIdentifier.uuidString) From 04f8fa2b9cfda2c157b152494b936f906f27e28f Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 6 Oct 2019 17:01:16 -0500 Subject: [PATCH 08/13] Bump cartfile rev --- Cartfile.resolved | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cartfile.resolved b/Cartfile.resolved index a24f5681de..87a5facd51 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -5,4 +5,4 @@ github "LoopKit/LoopKit" "9e480868330d66f4b781b9c1a4e6c434de070760" github "LoopKit/MKRingProgressView" "f548a5c64832be2d37d7c91b5800e284887a2a0a" github "LoopKit/dexcom-share-client-swift" "45b8908a04a60f2cba6ac07436c661cd0ee9a39c" github "i-schuetz/SwiftCharts" "0.6.5" -github "ps2/rileylink_ios" "4dfa9dd2c6f6ba0265a76c460727ea4ed75a7dbe" +github "ps2/rileylink_ios" "3b0aa012d233caac19d36725f5cb22e1e3b103a3" From e3fcd78b97f5b8a73fc3a54b62ed41c2d9cccef1 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 9 Oct 2019 19:31:02 -0500 Subject: [PATCH 09/13] Send any override changes when uploading loop status --- Loop/Managers/NightscoutDataManager.swift | 57 ++++++++++++----------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/Loop/Managers/NightscoutDataManager.swift b/Loop/Managers/NightscoutDataManager.swift index 70689f150c..1a73dafe17 100644 --- a/Loop/Managers/NightscoutDataManager.swift +++ b/Loop/Managers/NightscoutDataManager.swift @@ -50,6 +50,35 @@ final class NightscoutDataManager { lastSettingsUpdate = Date() uploadSettings() + uploadOverridesUpdates() + } + + private func uploadOverridesUpdates() { + guard let uploader = deviceManager.remoteDataManager.nightscoutService.uploader else { + return + } + + let (overrides, deletedOverrides, newAnchor) = deviceManager.loopManager.overrideHistory.queryByAnchor(overrideHistoryQueryAnchor) + + let updates = overrides.map { OverrideTreatment(override: $0) } + + let deletions = deletedOverrides.map { $0.syncIdentifier.uuidString } + uploader.deleteTreatmentsByClientId(deletions, completionHandler: { (error) in + if let error = error { + self.log.error("Overrides deletions failed to delete %{public}@: %{public}@", String(describing: deletions), String(describing: error)) + } else { + self.log.debug("Deleted ids: %@", deletions) + uploader.upload(updates) { (result) in + switch result { + case .failure(let error): + self.log.error("Failed to upload overrides %{public}@: %{public}@", String(describing: updates.map {$0.dictionaryRepresentation}), String(describing: error)) + case .success: + self.log.error("Uploaded overrides %{public}@", String(describing: updates.map {$0.dictionaryRepresentation})) + self.overrideHistoryQueryAnchor = newAnchor + } + } + } + }) } private func uploadSettings() { @@ -132,31 +161,6 @@ final class NightscoutDataManager { } } } - - // Upload overrides - let (overrides, deletedOverrides, newAnchor) = deviceManager.loopManager.overrideHistory.queryByAnchor(overrideHistoryQueryAnchor) - - let updates = overrides.map { OverrideTreatment(override: $0) } - - let deletions = deletedOverrides.map { $0.syncIdentifier.uuidString } - uploader.deleteTreatmentsByClientId(deletions, completionHandler: { (error) in - if let error = error { - self.log.error("Overrides deletions failed to delete %{public}@: %{public}@", String(describing: deletions), String(describing: error)) - } else { - self.log.debug("Deleted ids: %@", deletions) - } - }) - uploader.upload(updates) { (result) in - switch result { - case .failure(let error): - self.log.error("Failed to upload overrides %{public}@: %{public}@", String(describing: updates.map {$0.dictionaryRepresentation}), String(describing: error)) - case .success: - // Should join this result with deletion result before updating anchor - self.log.error("Uploaded overrides %{public}@", String(describing: updates.map {$0.dictionaryRepresentation})) - self.overrideHistoryQueryAnchor = newAnchor - } - } - } @objc func loopCompleted(_ note: Notification) { @@ -201,6 +205,8 @@ final class NightscoutDataManager { if self.lastSettingsUpdate > self.lastSettingsUpload { self.uploadSettings() } + + self.uploadOverridesUpdates() } } } @@ -357,7 +363,6 @@ final class NightscoutDataManager { } log.default("Uploading loop status") upload(pumpStatus: pumpStatus, loopStatus: loopStatus, deviceName: nil, firmwareVersion: nil, uploaderStatus: getUploaderStatus(), overrideStatus: overrideStatus) - } private func getUploaderStatus() -> UploaderStatus { From a069f02dbd40173ac50df4c7903e0e9802df68c6 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 9 Oct 2019 23:31:38 -0500 Subject: [PATCH 10/13] Bump carthage revisions --- Cartfile.resolved | 2 +- Loop/Managers/NightscoutDataManager.swift | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cartfile.resolved b/Cartfile.resolved index 87a5facd51..012e1ca8b3 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -5,4 +5,4 @@ github "LoopKit/LoopKit" "9e480868330d66f4b781b9c1a4e6c434de070760" github "LoopKit/MKRingProgressView" "f548a5c64832be2d37d7c91b5800e284887a2a0a" github "LoopKit/dexcom-share-client-swift" "45b8908a04a60f2cba6ac07436c661cd0ee9a39c" github "i-schuetz/SwiftCharts" "0.6.5" -github "ps2/rileylink_ios" "3b0aa012d233caac19d36725f5cb22e1e3b103a3" +github "ps2/rileylink_ios" "fb925edbb79147ceb8ebb9546731fe9ef66a43ad" diff --git a/Loop/Managers/NightscoutDataManager.swift b/Loop/Managers/NightscoutDataManager.swift index 1a73dafe17..bf124dc25a 100644 --- a/Loop/Managers/NightscoutDataManager.swift +++ b/Loop/Managers/NightscoutDataManager.swift @@ -67,7 +67,9 @@ final class NightscoutDataManager { if let error = error { self.log.error("Overrides deletions failed to delete %{public}@: %{public}@", String(describing: deletions), String(describing: error)) } else { - self.log.debug("Deleted ids: %@", deletions) + if deletions.count > 0 { + self.log.debug("Deleted ids: %@", deletions) + } uploader.upload(updates) { (result) in switch result { case .failure(let error): From 2d8c0b6c60412422eb4ab7733a04ffafaf468197 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Fri, 11 Oct 2019 16:35:42 -0500 Subject: [PATCH 11/13] Bump carthage revision --- Cartfile.resolved | 2 +- Loop/Managers/NightscoutDataManager.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cartfile.resolved b/Cartfile.resolved index 012e1ca8b3..96b9c69d13 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,7 +1,7 @@ github "LoopKit/Amplitude-iOS" "2137d5fd44bf630ed33e1e72d7af6d8f8612f270" github "LoopKit/CGMBLEKit" "0a368795c9c29c0dba4ec0b03a7e91cd36971155" github "LoopKit/G4ShareSpy" "27edd94e82bbef90bb67cbcee96e4a8f2f02dfbc" -github "LoopKit/LoopKit" "9e480868330d66f4b781b9c1a4e6c434de070760" +github "LoopKit/LoopKit" "f23ef4edd9a0186f1e8db1909f8bc88a89452f0f" github "LoopKit/MKRingProgressView" "f548a5c64832be2d37d7c91b5800e284887a2a0a" github "LoopKit/dexcom-share-client-swift" "45b8908a04a60f2cba6ac07436c661cd0ee9a39c" github "i-schuetz/SwiftCharts" "0.6.5" diff --git a/Loop/Managers/NightscoutDataManager.swift b/Loop/Managers/NightscoutDataManager.swift index bf124dc25a..68af4427d0 100644 --- a/Loop/Managers/NightscoutDataManager.swift +++ b/Loop/Managers/NightscoutDataManager.swift @@ -75,7 +75,7 @@ final class NightscoutDataManager { case .failure(let error): self.log.error("Failed to upload overrides %{public}@: %{public}@", String(describing: updates.map {$0.dictionaryRepresentation}), String(describing: error)) case .success: - self.log.error("Uploaded overrides %{public}@", String(describing: updates.map {$0.dictionaryRepresentation})) + self.log.debug("Uploaded overrides %@", String(describing: updates.map {$0.dictionaryRepresentation})) self.overrideHistoryQueryAnchor = newAnchor } } From c8119c67c771e6318157551da0cdcd1b3e30a976 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 13 Oct 2019 09:26:35 -0500 Subject: [PATCH 12/13] Fix typo, and log device token --- Cartfile.resolved | 2 +- Loop/AppDelegate.swift | 1 + Loop/Managers/NightscoutDataManager.swift | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cartfile.resolved b/Cartfile.resolved index 96b9c69d13..cff51edb18 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -5,4 +5,4 @@ github "LoopKit/LoopKit" "f23ef4edd9a0186f1e8db1909f8bc88a89452f0f" github "LoopKit/MKRingProgressView" "f548a5c64832be2d37d7c91b5800e284887a2a0a" github "LoopKit/dexcom-share-client-swift" "45b8908a04a60f2cba6ac07436c661cd0ee9a39c" github "i-schuetz/SwiftCharts" "0.6.5" -github "ps2/rileylink_ios" "fb925edbb79147ceb8ebb9546731fe9ef66a43ad" +github "ps2/rileylink_ios" "9880ace175bf7bf09c87375917f93e50ac4c14ea" diff --git a/Loop/AppDelegate.swift b/Loop/AppDelegate.swift index 1b3ca3bf48..df2430f732 100644 --- a/Loop/AppDelegate.swift +++ b/Loop/AppDelegate.swift @@ -85,6 +85,7 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) } let token = tokenParts.joined() + log.default("RemoteNotifications device token: \(token)") deviceManager.loopManager.settings.deviceToken = deviceToken } diff --git a/Loop/Managers/NightscoutDataManager.swift b/Loop/Managers/NightscoutDataManager.swift index 68af4427d0..ea8899ea15 100644 --- a/Loop/Managers/NightscoutDataManager.swift +++ b/Loop/Managers/NightscoutDataManager.swift @@ -568,6 +568,6 @@ private extension OverrideTreatment { duration = .indefinite } - self.init(startDate: override.startDate, enderedBy: enteredBy, reason: reason, duration: duration, correctionRange: nsTargetRange, insulinNeedsScaleFactor: override.settings.insulinNeedsScaleFactor, remoteAddress:remoteAddress, id: override.syncIdentifier.uuidString) + self.init(startDate: override.startDate, enteredBy: enteredBy, reason: reason, duration: duration, correctionRange: nsTargetRange, insulinNeedsScaleFactor: override.settings.insulinNeedsScaleFactor, remoteAddress:remoteAddress, id: override.syncIdentifier.uuidString) } } From 452d5a61f7bbd269a65323d266806df944b9ac23 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 13 Oct 2019 10:44:22 -0500 Subject: [PATCH 13/13] Carthage dependency revisions --- Cartfile | 10 +++++----- Cartfile.resolved | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cartfile b/Cartfile index e943f98c6f..ca66f13586 100644 --- a/Cartfile +++ b/Cartfile @@ -1,7 +1,7 @@ -github "LoopKit/LoopKit" "remote-overrides" -github "LoopKit/CGMBLEKit" "remote-overrides" +github "LoopKit/LoopKit" "dev" +github "LoopKit/CGMBLEKit" "dev" github "i-schuetz/SwiftCharts" == 0.6.5 -github "LoopKit/dexcom-share-client-swift" "remote-overrides" -github "LoopKit/G4ShareSpy" "remote-overrides" -github "ps2/rileylink_ios" "remote-overrides" +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 cff51edb18..aa6357ee5f 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,8 +1,8 @@ github "LoopKit/Amplitude-iOS" "2137d5fd44bf630ed33e1e72d7af6d8f8612f270" -github "LoopKit/CGMBLEKit" "0a368795c9c29c0dba4ec0b03a7e91cd36971155" -github "LoopKit/G4ShareSpy" "27edd94e82bbef90bb67cbcee96e4a8f2f02dfbc" -github "LoopKit/LoopKit" "f23ef4edd9a0186f1e8db1909f8bc88a89452f0f" +github "LoopKit/CGMBLEKit" "7417605dd898bf89378171941126c85d85dc642c" +github "LoopKit/G4ShareSpy" "e62d296067180c6659166272ff9cc406f470ec9e" +github "LoopKit/LoopKit" "a08405ec7a4e38fa96e39ae079114db30f393a2a" github "LoopKit/MKRingProgressView" "f548a5c64832be2d37d7c91b5800e284887a2a0a" -github "LoopKit/dexcom-share-client-swift" "45b8908a04a60f2cba6ac07436c661cd0ee9a39c" +github "LoopKit/dexcom-share-client-swift" "c4f3d48e56e5b3ad786486ccd1bbc753034096d2" github "i-schuetz/SwiftCharts" "0.6.5" -github "ps2/rileylink_ios" "9880ace175bf7bf09c87375917f93e50ac4c14ea" +github "ps2/rileylink_ios" "51d6a20cc63c0c0b2071a4a78b4065e9a11ba81f"