Skip to content

Commit d1ecad9

Browse files
author
Rick Pasetto
authored
LOOP-1769: Support for controlling debug features through AppGroup via a separate app (#445)
1 parent 048ce8a commit d1ecad9

File tree

9 files changed

+47
-19
lines changed

9 files changed

+47
-19
lines changed

Common/FeatureFlags.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,20 @@ extension FeatureFlagConfiguration : CustomDebugStringConvertible {
157157
"* simulatedCoreDataEnabled: \(simulatedCoreDataEnabled)",
158158
"* siriEnabled: \(siriEnabled)",
159159
"* automaticBolusEnabled: \(automaticBolusEnabled)",
160-
"* manualDoseEntryEnabled: \(manualDoseEntryEnabled)"
160+
"* manualDoseEntryEnabled: \(manualDoseEntryEnabled)",
161+
"* allowDebugFeatures: \(allowDebugFeatures)",
161162
].joined(separator: "\n")
162163
}
163164
}
165+
166+
extension FeatureFlagConfiguration {
167+
var allowDebugFeatures: Bool {
168+
if debugEnabled {
169+
return true
170+
}
171+
if UserDefaults.appGroup?.allowDebugFeatures ?? false {
172+
return true
173+
}
174+
return false
175+
}
176+
}

Loop.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
1D080CBD2473214A00356610 /* AlertStore.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1D080CBB2473214A00356610 /* AlertStore.xcdatamodeld */; };
2727
1D12D3B92548EFDD00B53E8B /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D12D3B82548EFDD00B53E8B /* main.swift */; };
2828
1D2609AD248EEB9900A6F258 /* LoopAlertsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D2609AC248EEB9900A6F258 /* LoopAlertsManager.swift */; };
29+
1D3F0F7526D59B6C004A5960 /* Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892A5D58222F0A27008961AB /* Debug.swift */; };
30+
1D3F0F7626D59DCD004A5960 /* Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892A5D58222F0A27008961AB /* Debug.swift */; };
31+
1D3F0F7726D59DCE004A5960 /* Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892A5D58222F0A27008961AB /* Debug.swift */; };
2932
1D49795824E7289700948F05 /* ServicesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D49795724E7289700948F05 /* ServicesViewModel.swift */; };
3033
1D4990E824A25931005CC357 /* FeatureFlags.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89E267FB2292456700A3F2AF /* FeatureFlags.swift */; };
3134
1D4A3E2D2478628500FD601B /* StoredAlert+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4A3E2B2478628500FD601B /* StoredAlert+CoreDataClass.swift */; };
@@ -3615,6 +3618,7 @@
36153618
439A7945211FE23A0041B75F /* NSUserActivity.swift in Sources */,
36163619
43A943881B926B7B0051FA24 /* ExtensionDelegate.swift in Sources */,
36173620
43511CEE220FC61700566C63 /* HUDRowController.swift in Sources */,
3621+
1D3F0F7526D59B6C004A5960 /* Debug.swift in Sources */,
36183622
892FB4CD22040104005293EC /* OverridePresetRow.swift in Sources */,
36193623
4F75F00220FCFE8C00B5570E /* GlucoseChartScene.swift in Sources */,
36203624
89E26800229267DF00A3F2AF /* Optional.swift in Sources */,
@@ -3836,6 +3840,7 @@
38363840
43BFF0CD1E466C8400FF19A9 /* StateColorPalette.swift in Sources */,
38373841
4FC8C8021DEB943800A1452E /* NSUserDefaults+StatusExtension.swift in Sources */,
38383842
4F70C2121DE900EA006380B7 /* StatusExtensionContext.swift in Sources */,
3843+
1D3F0F7626D59DCD004A5960 /* Debug.swift in Sources */,
38393844
4F70C1E11DE8DCA7006380B7 /* StatusViewController.swift in Sources */,
38403845
A90EF54425DEF0A000F32D61 /* OSLog.swift in Sources */,
38413846
);
@@ -3908,6 +3913,7 @@
39083913
E9B07FEE253BBC7100BAD8F8 /* OverrideIntentHandler.swift in Sources */,
39093914
E942DE9F253BE6A900AC532D /* NSTimeInterval.swift in Sources */,
39103915
E9B08016253BBD7300BAD8F8 /* UserDefaults+LoopIntents.swift in Sources */,
3916+
1D3F0F7726D59DCE004A5960 /* Debug.swift in Sources */,
39113917
E942DF34253BF87F00AC532D /* Intents.intentdefinition in Sources */,
39123918
E9B07F7F253BBA6500BAD8F8 /* IntentHandler.swift in Sources */,
39133919
);

Loop/Extensions/Debug.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//
88

99
var debugEnabled: Bool {
10-
#if DEBUG || IOS_SIMULATOR
10+
#if DEBUG || IOS_SIMULATOR || targetEnvironment(simulator)
1111
return true
1212
#else
1313
return false

Loop/Extensions/DeviceDataManager+DeviceStatus.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ extension DeviceDataManager {
8787
{
8888
return .openAppURL(url)
8989
} else if let cgmManagerUI = (cgmManager as? CGMManagerUI) {
90-
return .presentViewController(cgmManagerUI.settingsViewController(bluetoothProvider: bluetoothProvider, displayGlucoseUnitObservable: displayGlucoseUnitObservable, colorPalette: .default, allowDebugFeatures: FeatureFlags.mockTherapySettingsEnabled))
90+
return .presentViewController(cgmManagerUI.settingsViewController(bluetoothProvider: bluetoothProvider, displayGlucoseUnitObservable: displayGlucoseUnitObservable, colorPalette: .default, allowDebugFeatures: FeatureFlags.allowDebugFeatures))
9191
} else {
9292
return .setupNewCGM
9393
}
@@ -101,11 +101,11 @@ extension DeviceDataManager {
101101
return .takeNoAction
102102
} else if let pumpManagerHUDProvider = pumpManagerHUDProvider,
103103
let view = view,
104-
let action = pumpManagerHUDProvider.didTapOnHUDView(view, allowDebugFeatures: FeatureFlags.mockTherapySettingsEnabled)
104+
let action = pumpManagerHUDProvider.didTapOnHUDView(view, allowDebugFeatures: FeatureFlags.allowDebugFeatures)
105105
{
106106
return action
107107
} else if let pumpManager = pumpManager {
108-
return .presentViewController(pumpManager.settingsViewController(bluetoothProvider: bluetoothProvider, colorPalette: .default, allowDebugFeatures: FeatureFlags.mockTherapySettingsEnabled, allowedInsulinTypes: allowedInsulinTypes))
108+
return .presentViewController(pumpManager.settingsViewController(bluetoothProvider: bluetoothProvider, colorPalette: .default, allowDebugFeatures: FeatureFlags.allowDebugFeatures, allowedInsulinTypes: allowedInsulinTypes))
109109
} else {
110110
return .setupNewPump
111111
}

Loop/Managers/DeliveryUncertaintyAlertManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class DeliveryUncertaintyAlertManager {
2121
}
2222

2323
private func showUncertainDeliveryRecoveryView() {
24-
var controller = pumpManager.deliveryUncertaintyRecoveryViewController(colorPalette: .default, allowDebugFeatures: FeatureFlags.mockTherapySettingsEnabled)
24+
var controller = pumpManager.deliveryUncertaintyRecoveryViewController(colorPalette: .default, allowDebugFeatures: FeatureFlags.allowDebugFeatures)
2525
controller.completionDelegate = self
2626
self.alertPresenter.present(controller, animated: true)
2727
}

Loop/Managers/DeviceDataManager.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ final class DeviceDataManager {
391391
return .failure(UnknownPumpManagerIdentifierError())
392392
}
393393

394-
let result = pumpManagerUIType.setupViewController(initialSettings: settings, bluetoothProvider: bluetoothProvider, colorPalette: .default, allowDebugFeatures: FeatureFlags.mockTherapySettingsEnabled, allowedInsulinTypes: allowedInsulinTypes)
394+
let result = pumpManagerUIType.setupViewController(initialSettings: settings, bluetoothProvider: bluetoothProvider, colorPalette: .default, allowDebugFeatures: FeatureFlags.allowDebugFeatures, allowedInsulinTypes: allowedInsulinTypes)
395395
if case .createdAndOnboarded(let pumpManagerUI) = result {
396396
pumpManagerOnboarding(didCreatePumpManager: pumpManagerUI)
397397
pumpManagerOnboarding(didOnboardPumpManager: pumpManagerUI)
@@ -484,7 +484,7 @@ final class DeviceDataManager {
484484
return .failure(UnknownCGMManagerIdentifierError())
485485
}
486486

487-
let result = cgmManagerUIType.setupViewController(bluetoothProvider: bluetoothProvider, displayGlucoseUnitObservable: displayGlucoseUnitObservable, colorPalette: .default, allowDebugFeatures: FeatureFlags.mockTherapySettingsEnabled)
487+
let result = cgmManagerUIType.setupViewController(bluetoothProvider: bluetoothProvider, displayGlucoseUnitObservable: displayGlucoseUnitObservable, colorPalette: .default, allowDebugFeatures: FeatureFlags.allowDebugFeatures)
488488
if case .createdAndOnboarded(let cgmManagerUI) = result {
489489
cgmManagerOnboarding(didCreateCGMManager: cgmManagerUI)
490490
cgmManagerOnboarding(didOnboardCGMManager: cgmManagerUI)
@@ -751,7 +751,7 @@ extension DeviceDataManager: DeviceManagerDelegate {
751751
}
752752

753753
var allowDebugFeatures: Bool {
754-
FeatureFlags.mockTherapySettingsEnabled // NOTE: DEBUG FEATURES - DEBUG AND TEST ONLY
754+
FeatureFlags.allowDebugFeatures // NOTE: DEBUG FEATURES - DEBUG AND TEST ONLY
755755
}
756756
}
757757

Loop/Managers/OnboardingManager.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ extension OnboardingManager: CGMManagerProvider {
328328
return .failure(OnboardingError.invalidState)
329329
}
330330

331-
return .success(.userInteractionRequired(cgmManagerUI.settingsViewController(bluetoothProvider: self, displayGlucoseUnitObservable: deviceDataManager.displayGlucoseUnitObservable, colorPalette: .default, allowDebugFeatures: FeatureFlags.mockTherapySettingsEnabled)))
331+
return .success(.userInteractionRequired(cgmManagerUI.settingsViewController(bluetoothProvider: self, displayGlucoseUnitObservable: deviceDataManager.displayGlucoseUnitObservable, colorPalette: .default, allowDebugFeatures: FeatureFlags.allowDebugFeatures)))
332332
}
333333
}
334334

@@ -367,7 +367,7 @@ extension OnboardingManager: PumpManagerProvider {
367367
return .success(.createdAndOnboarded(pumpManager))
368368
}
369369

370-
return .success(.userInteractionRequired(pumpManager.settingsViewController(bluetoothProvider: self, colorPalette: .default, allowDebugFeatures: FeatureFlags.mockTherapySettingsEnabled, allowedInsulinTypes: deviceDataManager.allowedInsulinTypes)))
370+
return .success(.userInteractionRequired(pumpManager.settingsViewController(bluetoothProvider: self, colorPalette: .default, allowDebugFeatures: FeatureFlags.allowDebugFeatures, allowedInsulinTypes: deviceDataManager.allowedInsulinTypes)))
371371
}
372372
}
373373

@@ -405,7 +405,7 @@ extension OnboardingManager: TherapySettingsProvider {
405405
// MARK: - OnboardingProvider
406406

407407
extension OnboardingManager: OnboardingProvider {
408-
var allowDebugFeatures: Bool { FeatureFlags.mockTherapySettingsEnabled } // NOTE: DEBUG FEATURES - DEBUG AND TEST ONLY
408+
var allowDebugFeatures: Bool { FeatureFlags.allowDebugFeatures } // NOTE: DEBUG FEATURES - DEBUG AND TEST ONLY
409409
}
410410

411411
// MARK: - OnboardingUI

Loop/View Controllers/StatusTableViewController.swift

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,7 @@ final class StatusTableViewController: LoopChartsTableViewController {
14231423
}
14241424

14251425
private func onPumpTapped() {
1426-
guard var settingsViewController = deviceManager.pumpManager?.settingsViewController(bluetoothProvider: deviceManager.bluetoothProvider, colorPalette: .default, allowDebugFeatures: FeatureFlags.mockTherapySettingsEnabled, allowedInsulinTypes: deviceManager.allowedInsulinTypes) else {
1426+
guard var settingsViewController = deviceManager.pumpManager?.settingsViewController(bluetoothProvider: deviceManager.bluetoothProvider, colorPalette: .default, allowDebugFeatures: FeatureFlags.allowDebugFeatures, allowedInsulinTypes: deviceManager.allowedInsulinTypes) else {
14271427
// assert?
14281428
return
14291429
}
@@ -1438,7 +1438,7 @@ final class StatusTableViewController: LoopChartsTableViewController {
14381438
return
14391439
}
14401440

1441-
var settings = cgmManager.settingsViewController(bluetoothProvider: deviceManager.bluetoothProvider, displayGlucoseUnitObservable: deviceManager.displayGlucoseUnitObservable, colorPalette: .default, allowDebugFeatures: FeatureFlags.mockTherapySettingsEnabled)
1441+
var settings = cgmManager.settingsViewController(bluetoothProvider: deviceManager.bluetoothProvider, displayGlucoseUnitObservable: deviceManager.displayGlucoseUnitObservable, colorPalette: .default, allowDebugFeatures: FeatureFlags.allowDebugFeatures)
14421442
settings.cgmManagerOnboardingDelegate = deviceManager
14431443
settings.completionDelegate = self
14441444
show(settings, sender: self)
@@ -1625,7 +1625,7 @@ final class StatusTableViewController: LoopChartsTableViewController {
16251625
var rotateTimer: Timer?
16261626
let rotateTimerTimeout = TimeInterval.seconds(2)
16271627
private func maybeOpenDebugMenu() {
1628-
guard FeatureFlags.scenariosEnabled || FeatureFlags.simulatedCoreDataEnabled || FeatureFlags.mockTherapySettingsEnabled else {
1628+
guard FeatureFlags.allowDebugFeatures else {
16291629
return
16301630
}
16311631
// Opens the debug menu if you rotate the phone 6 times (or back & forth 3 times), each rotation within 2 secs.
@@ -1649,14 +1649,18 @@ final class StatusTableViewController: LoopChartsTableViewController {
16491649
}
16501650

16511651
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
1652-
if FeatureFlags.scenariosEnabled || FeatureFlags.simulatedCoreDataEnabled || FeatureFlags.mockTherapySettingsEnabled {
1653-
if motion == .motionShake {
1654-
presentDebugMenu()
1655-
}
1652+
guard FeatureFlags.allowDebugFeatures else {
1653+
return
1654+
}
1655+
if motion == .motionShake {
1656+
presentDebugMenu()
16561657
}
16571658
}
16581659

16591660
private func presentDebugMenu() {
1661+
guard FeatureFlags.allowDebugFeatures else {
1662+
return
1663+
}
16601664
guard FeatureFlags.scenariosEnabled || FeatureFlags.simulatedCoreDataEnabled || FeatureFlags.mockTherapySettingsEnabled else {
16611665
fatalError("\(#function) should be invoked only when scenarios, simulated core data, or mock therapy settings are enabled")
16621666
}

LoopCore/NSUserDefaults.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ extension UserDefaults {
2323
case overrideHistory = "com.loopkit.overrideHistory"
2424
case lastBedtimeQuery = "com.loopkit.Loop.lastBedtimeQuery"
2525
case bedtime = "com.loopkit.Loop.bedtime"
26+
case allowDebugFeatures = "com.loopkit.Loop.allowDebugFeatures"
2627
}
2728

2829
public static let appGroup = UserDefaults(suiteName: Bundle.main.appGroupSuiteName)
@@ -177,4 +178,8 @@ extension UserDefaults {
177178
set(newValue, forKey: Key.bedtime.rawValue)
178179
}
179180
}
181+
182+
public var allowDebugFeatures: Bool {
183+
return bool(forKey: Key.allowDebugFeatures.rawValue)
184+
}
180185
}

0 commit comments

Comments
 (0)