Skip to content

Commit 475fa61

Browse files
authored
Remote PR Set #3 (#2009)
* Remote handling rearchitecture * Move remote background handling to ServicesManager. Use notification to detect loop completion. Move handleRemoteNotification to ServicesManager * Add delegate for ServicesManager * Remove remote details from DeviceDataManager * Remove remote terms from ServicesManagerDelegate api * Respond only to loopFinished notifications * Remove unused method * Rename method * Update names * Update names * Remove more remote references in DeviceDataManager * Remove Remote 2.0 parts * Update enact override method name * Move validation to ServicesManager. Move ServiceManager delegation to LoopDataManager * Move bolus validation to ServicesManager
1 parent 8e947cb commit 475fa61

14 files changed

+330
-1055
lines changed

Loop.xcodeproj/project.pbxproj

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -355,12 +355,6 @@
355355
A98556852493F901000FD662 /* AlertStore+SimulatedCoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98556842493F901000FD662 /* AlertStore+SimulatedCoreData.swift */; };
356356
A987CD4924A58A0100439ADC /* ZipArchive.swift in Sources */ = {isa = PBXBuildFile; fileRef = A987CD4824A58A0100439ADC /* ZipArchive.swift */; };
357357
A999D40624663D18004C89D4 /* PumpManagerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A999D40524663D18004C89D4 /* PumpManagerError.swift */; };
358-
A99A114229A581F4007919CE /* BolusAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114129A581F4007919CE /* BolusAction.swift */; };
359-
A99A114429A5829A007919CE /* CarbAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114329A5829A007919CE /* CarbAction.swift */; };
360-
A99A114629A582A2007919CE /* OverrideAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114529A582A2007919CE /* OverrideAction.swift */; };
361-
A99A114E29A5879D007919CE /* BolusActionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114B29A5879C007919CE /* BolusActionTests.swift */; };
362-
A99A114F29A5879D007919CE /* CarbActionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114C29A5879C007919CE /* CarbActionTests.swift */; };
363-
A99A115029A5879D007919CE /* OverrideActionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114D29A5879C007919CE /* OverrideActionTests.swift */; };
364358
A9A056B324B93C62007CF06D /* CriticalEventLogExportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9A056B224B93C62007CF06D /* CriticalEventLogExportView.swift */; };
365359
A9A056B524B94123007CF06D /* CriticalEventLogExportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9A056B424B94123007CF06D /* CriticalEventLogExportViewModel.swift */; };
366360
A9A63F8E246B271600588D5B /* NSTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439897341CD2F7DE00223065 /* NSTimeInterval.swift */; };
@@ -1347,12 +1341,6 @@
13471341
A98556842493F901000FD662 /* AlertStore+SimulatedCoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AlertStore+SimulatedCoreData.swift"; sourceTree = "<group>"; };
13481342
A987CD4824A58A0100439ADC /* ZipArchive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipArchive.swift; sourceTree = "<group>"; };
13491343
A999D40524663D18004C89D4 /* PumpManagerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpManagerError.swift; sourceTree = "<group>"; };
1350-
A99A114129A581F4007919CE /* BolusAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BolusAction.swift; sourceTree = "<group>"; };
1351-
A99A114329A5829A007919CE /* CarbAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbAction.swift; sourceTree = "<group>"; };
1352-
A99A114529A582A2007919CE /* OverrideAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverrideAction.swift; sourceTree = "<group>"; };
1353-
A99A114B29A5879C007919CE /* BolusActionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BolusActionTests.swift; sourceTree = "<group>"; };
1354-
A99A114C29A5879C007919CE /* CarbActionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarbActionTests.swift; sourceTree = "<group>"; };
1355-
A99A114D29A5879C007919CE /* OverrideActionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OverrideActionTests.swift; sourceTree = "<group>"; };
13561344
A9A056B224B93C62007CF06D /* CriticalEventLogExportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CriticalEventLogExportView.swift; sourceTree = "<group>"; };
13571345
A9A056B424B94123007CF06D /* CriticalEventLogExportViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CriticalEventLogExportViewModel.swift; sourceTree = "<group>"; };
13581346
A9B607AF247F000F00792BE4 /* UserNotifications+Loop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserNotifications+Loop.swift"; sourceTree = "<group>"; };
@@ -2831,19 +2819,6 @@
28312819
A99A114029A581D6007919CE /* Remote */ = {
28322820
isa = PBXGroup;
28332821
children = (
2834-
A99A114129A581F4007919CE /* BolusAction.swift */,
2835-
A99A114329A5829A007919CE /* CarbAction.swift */,
2836-
A99A114529A582A2007919CE /* OverrideAction.swift */,
2837-
);
2838-
path = Remote;
2839-
sourceTree = "<group>";
2840-
};
2841-
A99A114A29A58789007919CE /* Remote */ = {
2842-
isa = PBXGroup;
2843-
children = (
2844-
A99A114B29A5879C007919CE /* BolusActionTests.swift */,
2845-
A99A114C29A5879C007919CE /* CarbActionTests.swift */,
2846-
A99A114D29A5879C007919CE /* OverrideActionTests.swift */,
28472822
);
28482823
path = Remote;
28492824
sourceTree = "<group>";
@@ -2859,7 +2834,6 @@
28592834
A9E6DFED246A0460005B1A1C /* Models */ = {
28602835
isa = PBXGroup;
28612836
children = (
2862-
A99A114A29A58789007919CE /* Remote */,
28632837
A9DFAFB224F0415E00950D1E /* CarbBackfillRequestUserInfoTests.swift */,
28642838
A963B279252CEBAE0062AA12 /* SetBolusUserInfoTests.swift */,
28652839
A9DFAFB424F048A000950D1E /* WatchHistoricalCarbsTests.swift */,
@@ -3890,7 +3864,6 @@
38903864
C17824A01E19CF9800D9D25C /* GlucoseThresholdTableViewController.swift in Sources */,
38913865
4372E487213C86240068E043 /* SampleValue.swift in Sources */,
38923866
437CEEE41CDE5C0A003C8C80 /* UIImage.swift in Sources */,
3893-
A99A114229A581F4007919CE /* BolusAction.swift in Sources */,
38943867
C1201E2C23ECDBD0002DA84A /* WatchContextRequestUserInfo.swift in Sources */,
38953868
1D49795824E7289700948F05 /* ServicesViewModel.swift in Sources */,
38963869
1D4A3E2D2478628500FD601B /* StoredAlert+CoreDataClass.swift in Sources */,
@@ -3954,7 +3927,6 @@
39543927
1D6B1B6726866D89009AC446 /* AlertPermissionsChecker.swift in Sources */,
39553928
4F08DE8F1E7BB871006741EA /* CollectionType+Loop.swift in Sources */,
39563929
A9F703772489D8AA00C98AD8 /* PersistentDeviceLog+SimulatedCoreData.swift in Sources */,
3957-
A99A114629A582A2007919CE /* OverrideAction.swift in Sources */,
39583930
E9B080B1253BDA6300BAD8F8 /* UserDefaults+LoopIntents.swift in Sources */,
39593931
C1AF062329426300002C1B19 /* ManualGlucoseEntryRow.swift in Sources */,
39603932
C148CEE724FD91BD00711B3B /* DeliveryUncertaintyAlertManager.swift in Sources */,
@@ -4005,7 +3977,6 @@
40053977
A9C62D842331700E00535612 /* DiagnosticLog+Subsystem.swift in Sources */,
40063978
895FE0952201234000FCF18A /* OverrideSelectionViewController.swift in Sources */,
40073979
C1EF747228D6A44A00C8C083 /* CrashRecoveryManager.swift in Sources */,
4008-
A99A114429A5829A007919CE /* CarbAction.swift in Sources */,
40093980
A9F66FC3247F451500096EA7 /* UIDevice+Loop.swift in Sources */,
40103981
439706E622D2E84900C81566 /* PredictionSettingTableViewCell.swift in Sources */,
40113982
430D85891F44037000AF2D4F /* HUDViewTableViewCell.swift in Sources */,
@@ -4177,12 +4148,10 @@
41774148
buildActionMask = 2147483647;
41784149
files = (
41794150
A9DF02CB24F72B9E00B7C988 /* CriticalEventLogTests.swift in Sources */,
4180-
A99A114F29A5879D007919CE /* CarbActionTests.swift in Sources */,
41814151
B44251B3252350CE00605937 /* ChartAxisValuesStaticGeneratorTests.swift in Sources */,
41824152
1D80313D24746274002810DF /* AlertStoreTests.swift in Sources */,
41834153
C1777A6625A125F100595963 /* ManualEntryDoseViewModelTests.swift in Sources */,
41844154
C16B984026B4898800256B05 /* DoseEnactorTests.swift in Sources */,
4185-
A99A115029A5879D007919CE /* OverrideActionTests.swift in Sources */,
41864155
A9A63F8E246B271600588D5B /* NSTimeInterval.swift in Sources */,
41874156
A9DFAFB324F0415E00950D1E /* CarbBackfillRequestUserInfoTests.swift in Sources */,
41884157
A963B27A252CEBAE0062AA12 /* SetBolusUserInfoTests.swift in Sources */,
@@ -4202,7 +4171,6 @@
42024171
B4CAD8792549D2540057946B /* LoopCompletionFreshnessTests.swift in Sources */,
42034172
1D8D55BC252274650044DBB6 /* BolusEntryViewModelTests.swift in Sources */,
42044173
A91E4C2124F867A700BE9213 /* StoredAlertTests.swift in Sources */,
4205-
A99A114E29A5879D007919CE /* BolusActionTests.swift in Sources */,
42064174
1DA7A84224476EAD008257F0 /* AlertManagerTests.swift in Sources */,
42074175
A91E4C2324F86F1000BE9213 /* CriticalEventLogExportManagerTests.swift in Sources */,
42084176
E9C58A7324DB4A2700487A17 /* LoopDataManagerTests.swift in Sources */,

Loop/Managers/DeviceDataManager.swift

Lines changed: 10 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,6 @@ final class DeviceDataManager {
407407
overrideHistory: overrideHistory,
408408
insulinDeliveryStore: doseStore.insulinDeliveryStore
409409
)
410-
411410

412411
settingsManager.remoteDataServicesManager = remoteDataServicesManager
413412

@@ -416,7 +415,10 @@ final class DeviceDataManager {
416415
alertManager: alertManager,
417416
analyticsServicesManager: analyticsServicesManager,
418417
loggingServicesManager: loggingServicesManager,
419-
remoteDataServicesManager: remoteDataServicesManager
418+
remoteDataServicesManager: remoteDataServicesManager,
419+
settingsManager: settingsManager,
420+
servicesManagerDelegate: loopManager,
421+
servicesManagerDosingDelegate: self
420422
)
421423

422424
let criticalEventLogs: [CriticalEventLog] = [settingsManager.settingsStore, glucoseStore, carbStore, dosingDecisionStore, doseStore, deviceLog, alertManager.alertStore]
@@ -1339,6 +1341,7 @@ extension DeviceDataManager: LoopDataManagerDelegate {
13391341
self.crashRecoveryManager.dosingFinished()
13401342
}
13411343
}
1344+
13421345
}
13431346

13441347
extension Notification.Name {
@@ -1347,152 +1350,14 @@ extension Notification.Name {
13471350
static let PumpEventsAdded = Notification.Name(rawValue: "com.loopKit.notification.PumpEventsAdded")
13481351
}
13491352

1350-
// MARK: - Remote Notification Handling
1351-
extension DeviceDataManager {
1352-
1353-
func handleRemoteNotification(_ notification: [String: AnyObject]) {
1354-
Task {
1355-
let backgroundTask = await beginBackgroundTask(name: "Remote Data Upload")
1356-
await handleRemoteNotification(notification)
1357-
await endBackgroundTask(backgroundTask)
1358-
}
1359-
}
1360-
1361-
func handleRemoteNotification(_ notification: [String: AnyObject]) async {
1362-
1363-
defer {
1364-
log.default("Remote Notification: Finished handling")
1365-
}
1366-
1367-
guard FeatureFlags.remoteCommandsEnabled else {
1368-
log.error("Remote Notification: Remote Commands not enabled.")
1369-
return
1370-
}
1371-
1372-
let command: RemoteCommand
1373-
do {
1374-
command = try await remoteDataServicesManager.commandFromPushNotification(notification)
1375-
} catch {
1376-
log.error("Remote Notification: Parse Error: %{public}@", String(describing: error))
1377-
return
1378-
}
1379-
1380-
await handleRemoteCommand(command)
1381-
}
1382-
1383-
func handleRemoteCommand(_ command: RemoteCommand) async {
1384-
1385-
log.default("Remote Notification: Handling command %{public}@", String(describing: command))
1386-
1387-
switch command.action {
1388-
case .temporaryScheduleOverride(let overrideAction):
1389-
do {
1390-
try command.validate()
1391-
try await handleOverrideAction(overrideAction)
1392-
} catch {
1393-
log.error("Remote Notification: Override Action Error: %{public}@", String(describing: error))
1394-
}
1395-
case .cancelTemporaryOverride(let overrideCancelAction):
1396-
do {
1397-
try command.validate()
1398-
try await handleOverrideCancelAction(overrideCancelAction)
1399-
} catch {
1400-
log.error("Remote Notification: Override Action Cancel Error: %{public}@", String(describing: error))
1401-
}
1402-
case .bolusEntry(let bolusAction):
1403-
do {
1404-
try command.validate()
1405-
try await handleBolusAction(bolusAction)
1406-
} catch {
1407-
await NotificationManager.sendRemoteBolusFailureNotification(for: error, amount: bolusAction.amountInUnits)
1408-
log.error("Remote Notification: Bolus Action Error: %{public}@", String(describing: error))
1409-
}
1410-
case .carbsEntry(let carbAction):
1411-
do {
1412-
try command.validate()
1413-
try await handleCarbAction(carbAction)
1414-
} catch {
1415-
await NotificationManager.sendRemoteCarbEntryFailureNotification(for: error, amountInGrams: carbAction.amountInGrams)
1416-
log.error("Remote Notification: Carb Action Error: %{public}@", String(describing: error))
1417-
}
1418-
}
1419-
}
1420-
1421-
//Remote Overrides
1422-
1423-
func handleOverrideAction(_ action: OverrideAction) async throws {
1424-
let remoteOverride = try action.toValidOverride(allowedPresets: loopManager.settings.overridePresets)
1425-
await activateRemoteOverride(remoteOverride)
1426-
}
1427-
1428-
func handleOverrideCancelAction(_ action: OverrideCancelAction) async throws {
1429-
await activateRemoteOverride(nil)
1430-
}
1431-
1432-
func activateRemoteOverride(_ remoteOverride: TemporaryScheduleOverride?) async {
1433-
loopManager.mutateSettings { settings in settings.scheduleOverride = remoteOverride }
1434-
await remoteDataServicesManager.triggerUpload(for: .overrides)
1435-
}
1436-
1437-
//Remote Bolus
1438-
1439-
func handleBolusAction(_ action: BolusAction) async throws {
1440-
let validBolusAmount = try action.toValidBolusAmount(maximumBolus: loopManager.settings.maximumBolus)
1441-
try await self.enactBolus(units: validBolusAmount, activationType: .manualNoRecommendation)
1442-
await remoteDataServicesManager.triggerUpload(for: .dose)
1443-
self.analyticsServicesManager.didBolus(source: "Remote", units: validBolusAmount)
1444-
}
1445-
1446-
//Remote Carb Entry
1447-
1448-
func handleCarbAction(_ action: CarbAction) async throws {
1449-
let candidateCarbEntry = try action.toValidCarbEntry(defaultAbsorptionTime: carbStore.defaultAbsorptionTimes.medium,
1450-
minAbsorptionTime: LoopConstants.minCarbAbsorptionTime,
1451-
maxAbsorptionTime: LoopConstants.maxCarbAbsorptionTime,
1452-
maxCarbEntryQuantity: LoopConstants.maxCarbEntryQuantity.doubleValue(for: .gram()),
1453-
maxCarbEntryPastTime: LoopConstants.maxCarbEntryPastTime,
1454-
maxCarbEntryFutureTime: LoopConstants.maxCarbEntryFutureTime
1455-
)
1456-
1457-
let _ = try await addRemoteCarbEntry(candidateCarbEntry)
1458-
await remoteDataServicesManager.triggerUpload(for: .carb)
1459-
}
1460-
1461-
//Can't add this concurrency wrapper method to LoopKit due to the minimum iOS version
1462-
func addRemoteCarbEntry(_ carbEntry: NewCarbEntry) async throws -> StoredCarbEntry {
1463-
return try await withCheckedThrowingContinuation { continuation in
1464-
carbStore.addCarbEntry(carbEntry) { result in
1465-
switch result {
1466-
case .success(let storedCarbEntry):
1467-
self.analyticsServicesManager.didAddCarbs(source: "Remote", amount: carbEntry.quantity.doubleValue(for: .gram()))
1468-
continuation.resume(returning: storedCarbEntry)
1469-
case .failure(let error):
1470-
continuation.resume(throwing: error)
1471-
}
1472-
}
1473-
}
1474-
}
1475-
1476-
//Background Uploads
1353+
// MARK: - ServicesManagerDosingDelegate
1354+
1355+
extension DeviceDataManager: ServicesManagerDosingDelegate {
14771356

1478-
func beginBackgroundTask(name: String) async -> UIBackgroundTaskIdentifier? {
1479-
var backgroundTask: UIBackgroundTaskIdentifier?
1480-
backgroundTask = await UIApplication.shared.beginBackgroundTask(withName: name) {
1481-
guard let backgroundTask = backgroundTask else {return}
1482-
Task {
1483-
await UIApplication.shared.endBackgroundTask(backgroundTask)
1484-
}
1485-
1486-
self.log.error("Background Task Expired: %{public}@", name)
1487-
}
1488-
1489-
return backgroundTask
1357+
func deliverBolus(amountInUnits: Double) async throws {
1358+
try await enactBolus(units: amountInUnits, activationType: .manualNoRecommendation)
14901359
}
14911360

1492-
func endBackgroundTask(_ backgroundTask: UIBackgroundTaskIdentifier?) async {
1493-
guard let backgroundTask else {return}
1494-
await UIApplication.shared.endBackgroundTask(backgroundTask)
1495-
}
14961361
}
14971362

14981363
// MARK: - Critical Event Log Export

Loop/Managers/LoopAppManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ class LoopAppManager: NSObject {
349349
guard let notification = notification else {
350350
return false
351351
}
352-
deviceDataManager?.handleRemoteNotification(notification)
352+
deviceDataManager?.servicesManager.handleRemoteNotification(notification)
353353
return true
354354
}
355355

0 commit comments

Comments
 (0)