Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions Trio.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,11 @@
3EF667132FE48509009FB31A /* BasalDeliveryState+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EF667122FE48502009FB31A /* BasalDeliveryState+Extension.swift */; };
3F23E18680094E6DA98628E4 /* QuickPickBolusesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A54068ABDAE4898B243DF14 /* QuickPickBolusesView.swift */; };
41740E936552456AAC0EDAC3 /* SettingsSearchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3919BBB515547118D684CA2 /* SettingsSearchTests.swift */; };
A15B00312F30AA0100AB0C31 /* SettingsBackupTestFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00412F30AA0100AB0C41 /* SettingsBackupTestFixtures.swift */; };
A15B00322F30AA0100AB0C32 /* SettingsBackupCodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00422F30AA0100AB0C42 /* SettingsBackupCodableTests.swift */; };
A15B00332F30AA0100AB0C33 /* SettingsImportApplierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00432F30AA0100AB0C43 /* SettingsImportApplierTests.swift */; };
A15B00342F30AA0100AB0C34 /* SettingsBackupE2ETests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00442F30AA0100AB0C44 /* SettingsBackupE2ETests.swift */; };
A15B00352F30AA0100AB0C35 /* SettingsImportPresetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00452F30AA0100AB0C45 /* SettingsImportPresetTests.swift */; };
45252C95D220E796FDB3B022 /* ConfigEditorDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A87AA037BD079BA3528BA /* ConfigEditorDataFlow.swift */; };
45717281F743594AA9D87191 /* ConfigEditorRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 920DDB21E5D0EB813197500D /* ConfigEditorRootView.swift */; };
49090A8D2E9FE8D200D0F5DB /* GarminWatchSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49090A8C2E9FE8D200D0F5DB /* GarminWatchSettings.swift */; };
Expand Down Expand Up @@ -599,6 +604,16 @@
C2AA6CF72E1A734A00BF6C16 /* SettingsExportProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2AA6CF32E1A734A00BF6C16 /* SettingsExportProvider.swift */; };
C2AA6CF82E1A734A00BF6C16 /* SettingsExportDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2AA6CF22E1A734A00BF6C16 /* SettingsExportDataFlow.swift */; };
C2AA6CF92E1A734A00BF6C16 /* SettingsExportStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2AA6CF42E1A734A00BF6C16 /* SettingsExportStateModel.swift */; };
A15B00112F30AA0100AB0C11 /* SettingsBackup.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00012F30AA0100AB0C01 /* SettingsBackup.swift */; };
A15B00122F30AA0100AB0C12 /* SettingsImportDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00022F30AA0100AB0C02 /* SettingsImportDataFlow.swift */; };
A15B00132F30AA0100AB0C13 /* SettingsImportProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00032F30AA0100AB0C03 /* SettingsImportProvider.swift */; };
A15B00142F30AA0100AB0C14 /* SettingsImportStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00042F30AA0100AB0C04 /* SettingsImportStateModel.swift */; };
A15B00152F30AA0100AB0C15 /* SettingsImportApplier.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00052F30AA0100AB0C05 /* SettingsImportApplier.swift */; };
A15B00162F30AA0100AB0C16 /* SettingsBackupPresetLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00062F30AA0100AB0C06 /* SettingsBackupPresetLoader.swift */; };
A15B00172F30AA0100AB0C17 /* SettingsBackupPresetApplier.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00072F30AA0100AB0C07 /* SettingsBackupPresetApplier.swift */; };
A15B00182F30AA0100AB0C18 /* SettingsImportRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00082F30AA0100AB0C08 /* SettingsImportRootView.swift */; };
A15B00192F30AA0100AB0C19 /* OnboardingStateModel+BackupImport.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B00092F30AA0100AB0C09 /* OnboardingStateModel+BackupImport.swift */; };
A15B001A2F30AA0100AB0C1A /* TrioBackupImportStepView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15B000A2F30AA0100AB0C0A /* TrioBackupImportStepView.swift */; };
C2BA6B972F758E7500348E6A /* WatchNotificationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2BA6B962F758E7500348E6A /* WatchNotificationHandler.swift */; };
C2BA6B992F758E7600348E6A /* NotificationIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2BA6B982F758E7600348E6A /* NotificationIdentifiers.swift */; };
C2BA6B9A2F7593C300348E6A /* NotificationIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2BA6B982F758E7600348E6A /* NotificationIdentifiers.swift */; };
Expand Down Expand Up @@ -1418,6 +1433,11 @@
B015AFE12E500000000D7351 /* BolusSafetyValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BolusSafetyValidator.swift; sourceTree = "<group>"; };
B015AFE42E500000000D7351 /* BolusSafetyValidatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BolusSafetyValidatorTests.swift; sourceTree = "<group>"; };
B3919BBB515547118D684CA2 /* SettingsSearchTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SettingsSearchTests.swift; sourceTree = "<group>"; };
A15B00412F30AA0100AB0C41 /* SettingsBackupTestFixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsBackupTestFixtures.swift; sourceTree = "<group>"; };
A15B00422F30AA0100AB0C42 /* SettingsBackupCodableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsBackupCodableTests.swift; sourceTree = "<group>"; };
A15B00432F30AA0100AB0C43 /* SettingsImportApplierTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsImportApplierTests.swift; sourceTree = "<group>"; };
A15B00442F30AA0100AB0C44 /* SettingsBackupE2ETests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsBackupE2ETests.swift; sourceTree = "<group>"; };
A15B00452F30AA0100AB0C45 /* SettingsImportPresetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsImportPresetTests.swift; sourceTree = "<group>"; };
B6E925122EB3932A0076D719 /* OmnipodKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = OmnipodKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B9B5C0607505A38F256BF99A /* CGMSettingsDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CGMSettingsDataFlow.swift; sourceTree = "<group>"; };
BA49538D56989D8DA6FCF538 /* TargetsEditorDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TargetsEditorDataFlow.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1613,6 +1633,16 @@
C2AA6CF22E1A734A00BF6C16 /* SettingsExportDataFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsExportDataFlow.swift; sourceTree = "<group>"; };
C2AA6CF32E1A734A00BF6C16 /* SettingsExportProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsExportProvider.swift; sourceTree = "<group>"; };
C2AA6CF42E1A734A00BF6C16 /* SettingsExportStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsExportStateModel.swift; sourceTree = "<group>"; };
A15B00012F30AA0100AB0C01 /* SettingsBackup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsBackup.swift; sourceTree = "<group>"; };
A15B00022F30AA0100AB0C02 /* SettingsImportDataFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsImportDataFlow.swift; sourceTree = "<group>"; };
A15B00032F30AA0100AB0C03 /* SettingsImportProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsImportProvider.swift; sourceTree = "<group>"; };
A15B00042F30AA0100AB0C04 /* SettingsImportStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsImportStateModel.swift; sourceTree = "<group>"; };
A15B00052F30AA0100AB0C05 /* SettingsImportApplier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsImportApplier.swift; sourceTree = "<group>"; };
A15B00062F30AA0100AB0C06 /* SettingsBackupPresetLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsBackupPresetLoader.swift; sourceTree = "<group>"; };
A15B00072F30AA0100AB0C07 /* SettingsBackupPresetApplier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsBackupPresetApplier.swift; sourceTree = "<group>"; };
A15B00082F30AA0100AB0C08 /* SettingsImportRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsImportRootView.swift; sourceTree = "<group>"; };
A15B00092F30AA0100AB0C09 /* OnboardingStateModel+BackupImport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OnboardingStateModel+BackupImport.swift"; sourceTree = "<group>"; };
A15B000A2F30AA0100AB0C0A /* TrioBackupImportStepView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrioBackupImportStepView.swift; sourceTree = "<group>"; };
C2BA6B962F758E7500348E6A /* WatchNotificationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchNotificationHandler.swift; sourceTree = "<group>"; };
C2BA6B982F758E7600348E6A /* NotificationIdentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationIdentifiers.swift; sourceTree = "<group>"; };
C377490C77661D75E8C50649 /* ManualTempBasalRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ManualTempBasalRootView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2275,6 +2305,7 @@
9E56E3626FAD933385101B76 /* History */,
195D80B22AF696EE00D25097 /* DynamicSettings */,
C2AA6CF52E1A734A00BF6C16 /* SettingsExport */,
A15B00212F30AA0100AB0C21 /* SettingsImport */,
DD17454C2C55CA0200211FAC /* GeneralSettings */,
BD1179602F4E22C100F90001 /* GlucoseAlerts */,
BD11799A2F4E22C100F90001 /* DeviceAlarms */,
Expand Down Expand Up @@ -2754,6 +2785,7 @@
E592A36F2CEEC01E009A472C /* ContactTrickEntry.swift */,
3811DF0125CA9FEA00A708ED /* Credentials.swift */,
DD3D60302F0377350021A33B /* ExportSetting.swift */,
A15B00012F30AA0100AB0C01 /* SettingsBackup.swift */,
DD3078692D42F94000DE0490 /* GarminDevice.swift */,
49090A8C2E9FE8D200D0F5DB /* GarminWatchSettings.swift */,
DD4FFF322D458EE600B6CFF9 /* GarminWatchState.swift */,
Expand Down Expand Up @@ -3021,6 +3053,10 @@
CE1F6DD82BADF4620064EB8D /* PluginManagerTests.swift */,
3B5CD2C72D4AECD500CE213C /* OpenAPSSwiftTests */,
B3919BBB515547118D684CA2 /* SettingsSearchTests.swift */,
A15B00412F30AA0100AB0C41 /* SettingsBackupTestFixtures.swift */,
A15B00422F30AA0100AB0C42 /* SettingsBackupCodableTests.swift */,
A15B00432F30AA0100AB0C43 /* SettingsImportApplierTests.swift */,
A15B00442F30AA0100AB0C44 /* SettingsBackupE2ETests.swift */,
BD8FC0532D66186000B95AED /* TestError.swift */,
C39FF1EC12CF4B1EBB13BE26 /* NightscoutUploadSerializerTests.swift */,
BD8FC0702D661B0000B95AED /* TidepoolTherapySettingsTests.swift */,
Expand Down Expand Up @@ -3576,6 +3612,7 @@
BD8E6B202D9036CA00ABF8FA /* OnboardingProvider.swift */,
BD47FD1A2D88AB4A0043966B /* OnboardingStateModel.swift */,
DDF68FFB2D9ECF77008BF16C /* OnboardingStateModel+Nightscout.swift */,
A15B00092F30AA0100AB0C09 /* OnboardingStateModel+BackupImport.swift */,
BD47FD152D88AAD80043966B /* View */,
);
path = Onboarding;
Expand Down Expand Up @@ -3609,6 +3646,7 @@
DD3F1F842D9DD83B00DCE7B3 /* DeliveryLimitsStepView.swift */,
DD3F1F822D9DC78300DCE7B3 /* UnitSelectionStepView.swift */,
BD47FD162D88AAEF0043966B /* CompletedStepView.swift */,
A15B000A2F30AA0100AB0C0A /* TrioBackupImportStepView.swift */,
);
path = OnboardingSteps;
sourceTree = "<group>";
Expand Down Expand Up @@ -3670,6 +3708,7 @@
BD8FC05A2D6618AF00B95AED /* DeterminationStorageTests.swift */,
BD8FC05F2D6619DB00B95AED /* CarbsStorageTests.swift */,
BD8FC0612D6619E600B95AED /* OverrideStorageTests.swift */,
A15B00452F30AA0100AB0C45 /* SettingsImportPresetTests.swift */,
BD8FC0632D6619EF00B95AED /* TempTargetStorageTests.swift */,
BD8FC0652D661A0000B95AED /* GlucoseStorageTests.swift */,
);
Expand Down Expand Up @@ -3787,6 +3826,28 @@
path = SettingsExport;
sourceTree = "<group>";
};
A15B00212F30AA0100AB0C21 /* SettingsImport */ = {
isa = PBXGroup;
children = (
A15B00222F30AA0100AB0C22 /* View */,
A15B00022F30AA0100AB0C02 /* SettingsImportDataFlow.swift */,
A15B00032F30AA0100AB0C03 /* SettingsImportProvider.swift */,
A15B00042F30AA0100AB0C04 /* SettingsImportStateModel.swift */,
A15B00052F30AA0100AB0C05 /* SettingsImportApplier.swift */,
A15B00062F30AA0100AB0C06 /* SettingsBackupPresetLoader.swift */,
A15B00072F30AA0100AB0C07 /* SettingsBackupPresetApplier.swift */,
);
path = SettingsImport;
sourceTree = "<group>";
};
A15B00222F30AA0100AB0C22 /* View */ = {
isa = PBXGroup;
children = (
A15B00082F30AA0100AB0C08 /* SettingsImportRootView.swift */,
);
path = View;
sourceTree = "<group>";
};
C2C98283C436DB934D7E7994 /* Treatments */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -5294,6 +5355,16 @@
C2AA6CF72E1A734A00BF6C16 /* SettingsExportProvider.swift in Sources */,
C2AA6CF82E1A734A00BF6C16 /* SettingsExportDataFlow.swift in Sources */,
C2AA6CF92E1A734A00BF6C16 /* SettingsExportStateModel.swift in Sources */,
A15B00112F30AA0100AB0C11 /* SettingsBackup.swift in Sources */,
A15B00122F30AA0100AB0C12 /* SettingsImportDataFlow.swift in Sources */,
A15B00132F30AA0100AB0C13 /* SettingsImportProvider.swift in Sources */,
A15B00142F30AA0100AB0C14 /* SettingsImportStateModel.swift in Sources */,
A15B00152F30AA0100AB0C15 /* SettingsImportApplier.swift in Sources */,
A15B00162F30AA0100AB0C16 /* SettingsBackupPresetLoader.swift in Sources */,
A15B00172F30AA0100AB0C17 /* SettingsBackupPresetApplier.swift in Sources */,
A15B00182F30AA0100AB0C18 /* SettingsImportRootView.swift in Sources */,
A15B00192F30AA0100AB0C19 /* OnboardingStateModel+BackupImport.swift in Sources */,
A15B001A2F30AA0100AB0C1A /* TrioBackupImportStepView.swift in Sources */,
3811DE4325C9D4A100A708ED /* SettingsProvider.swift in Sources */,
45252C95D220E796FDB3B022 /* ConfigEditorDataFlow.swift in Sources */,
CE7CA34E2A064973004BE681 /* AppShortcuts.swift in Sources */,
Expand Down Expand Up @@ -5706,6 +5777,11 @@
DD30BA002E0745C400DA677C /* DetermineBasalDeltaCalculationTests.swift in Sources */,
BD8FC05E2D6618CE00B95AED /* BolusCalculatorTests.swift in Sources */,
41740E936552456AAC0EDAC3 /* SettingsSearchTests.swift in Sources */,
A15B00312F30AA0100AB0C31 /* SettingsBackupTestFixtures.swift in Sources */,
A15B00322F30AA0100AB0C32 /* SettingsBackupCodableTests.swift in Sources */,
A15B00332F30AA0100AB0C33 /* SettingsImportApplierTests.swift in Sources */,
A15B00342F30AA0100AB0C34 /* SettingsBackupE2ETests.swift in Sources */,
A15B00352F30AA0100AB0C35 /* SettingsImportPresetTests.swift in Sources */,
B015AFE52E500000000D7351 /* BolusSafetyValidatorTests.swift in Sources */,
BD8FC0712D661B0000B95AED /* TidepoolTherapySettingsTests.swift in Sources */,
CA03000000000000000010C2 /* AlertCatalogRegistryOmniFaultTests.swift in Sources */,
Expand Down
12 changes: 12 additions & 0 deletions Trio/Sources/APS/DeviceDataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ protocol DeviceDataManager: GlucoseSource {

func heartbeat(date: Date)
func createBolusProgressReporter() -> DoseProgressReporter?
func adoptPumpManager(fromRawValue rawValue: [String: Any]) -> Bool
var alertHistoryStorage: AlertHistoryStorage! { get }
}

Expand Down Expand Up @@ -261,6 +262,17 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
}
}

/// Adopts pump manager state restored from a settings backup. Assigning `pumpManager` wires
/// the delegate, persists the state, and re-syncs delivery limits — the same path as app start.
/// Returns false when the state cannot be reconstructed (unknown manager type or invalid state).
func adoptPumpManager(fromRawValue rawValue: [String: Any]) -> Bool {
guard let manager = pumpManagerFromRawValue(rawValue) else {
return false
}
pumpManager = manager
return true
}

func createBolusProgressReporter() -> DoseProgressReporter? {
pumpManager?.createBolusProgressReporter(reportingOn: processQueue)
}
Expand Down
16 changes: 16 additions & 0 deletions Trio/Sources/APS/FetchGlucoseManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import UIKit

protocol FetchGlucoseManager: SourceInfoProvider {
func updateGlucoseSource(cgmGlucoseSourceType: CGMType, cgmGlucosePluginId: String, newManager: CGMManagerUI?)
func adoptCGMManagerState(_ rawValue: CGMManager.RawValue, cgmGlucosePluginId: String) -> Bool
func deleteGlucoseSource() async
func removeCalibrations()
func newGlucoseFromCgmManager(newGlucose: [BloodGlucose])
Expand Down Expand Up @@ -179,6 +180,21 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable {
calibrationService.removeAllCalibrations()
}

/// Adopts CGM manager state restored from a settings backup. The source identifiers must be
/// set before `updateGlucoseSource` runs so its "source changed" branch does not wipe the
/// adopted state, and so the plugin type resolves against the imported plugin id.
/// Returns false when the state cannot be reconstructed (plugin not compiled in, invalid state).
func adoptCGMManagerState(_ rawValue: CGMManager.RawValue, cgmGlucosePluginId pluginId: String) -> Bool {
removeCalibrations()
cgmManager = nil
glucoseSource = nil
cgmGlucoseSourceType = .plugin
cgmGlucosePluginId = pluginId
rawCGMManager = rawValue
updateGlucoseSource(cgmGlucoseSourceType: .plugin, cgmGlucosePluginId: pluginId)
return cgmManager != nil
}

@MainActor func deleteGlucoseSource() async {
cgmManager = nil
glucoseSource = nil
Expand Down
6 changes: 0 additions & 6 deletions Trio/Sources/Models/ExportSetting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,3 @@ struct ExportSetting: Codable {
self.unit = unit
}
}

struct ExportSettingPayload: Codable {
let exportFormat: String
let exportDate: String
let settings: [ExportSetting]
}
Loading