Skip to content

Commit 2fa57b2

Browse files
authored
Default migrationStep to latest so fresh installs skip migrations (#631)
Previously migrationStep defaulted to 0, forcing every fresh install to iterate through every migration. Set the default to the latest step (7) and update other StorageValue defaults to match the post-migration final state on a fresh install: - snoozerPosition: .menu -> .position3 - nightscoutPosition: .position3 -> .position4 - remotePosition: .position4 -> .menu - hasSeenFatProteinOrderChange: false -> true Add reminder comments at the migrationStep declaration and at the runMigrationsIfNeeded() block so future authors bump the default and update affected defaults whenever a new step is added.
1 parent 8b2c4a1 commit 2fa57b2

2 files changed

Lines changed: 16 additions & 7 deletions

File tree

LoopFollow/Storage/Storage.swift

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Storage {
3333
var mealWithFatProtein = StorageValue<Bool>(key: "mealWithFatProtein", defaultValue: false)
3434

3535
// TODO: This flag can be deleted in March 2027. Check the commit for other places to cleanup.
36-
var hasSeenFatProteinOrderChange = StorageValue<Bool>(key: "hasSeenFatProteinOrderChange", defaultValue: false)
36+
var hasSeenFatProteinOrderChange = StorageValue<Bool>(key: "hasSeenFatProteinOrderChange", defaultValue: true)
3737

3838
var backgroundRefreshType = StorageValue<BackgroundRefreshType>(key: "backgroundRefreshType", defaultValue: .silentTune)
3939

@@ -207,7 +207,10 @@ class Storage {
207207
var nsWriteAuth = StorageValue<Bool>(key: "nsWriteAuth", defaultValue: false)
208208
var nsAdminAuth = StorageValue<Bool>(key: "nsAdminAuth", defaultValue: false)
209209

210-
var migrationStep = StorageValue<Int>(key: "migrationStep", defaultValue: 0)
210+
// When adding a new migration step in `runMigrationsIfNeeded()`, bump this default
211+
// to the new latest step number so fresh installs skip all migrations. Other defaults
212+
// in this file must reflect the post-migration final state for a fresh install.
213+
var migrationStep = StorageValue<Int>(key: "migrationStep", defaultValue: 7)
211214

212215
var persistentNotification = StorageValue<Bool>(key: "persistentNotification", defaultValue: false)
213216
var persistentNotificationLastBGTime = StorageValue<Date>(key: "persistentNotificationLastBGTime", defaultValue: .distantPast)
@@ -219,9 +222,9 @@ class Storage {
219222
// Tab positions - which position each item is in (positions 1-4 are customizable, 5 is always Menu)
220223
var homePosition = StorageValue<TabPosition>(key: "homePosition", defaultValue: .position1)
221224
var alarmsPosition = StorageValue<TabPosition>(key: "alarmsPosition", defaultValue: .position2)
222-
var snoozerPosition = StorageValue<TabPosition>(key: "snoozerPosition", defaultValue: .menu)
223-
var nightscoutPosition = StorageValue<TabPosition>(key: "nightscoutPosition", defaultValue: .position3)
224-
var remotePosition = StorageValue<TabPosition>(key: "remotePosition", defaultValue: .position4)
225+
var snoozerPosition = StorageValue<TabPosition>(key: "snoozerPosition", defaultValue: .position3)
226+
var nightscoutPosition = StorageValue<TabPosition>(key: "nightscoutPosition", defaultValue: .position4)
227+
var remotePosition = StorageValue<TabPosition>(key: "remotePosition", defaultValue: .menu)
225228
var statisticsPosition = StorageValue<TabPosition>(key: "statisticsPosition", defaultValue: .menu)
226229
var treatmentsPosition = StorageValue<TabPosition>(key: "treatmentsPosition", defaultValue: .menu)
227230

@@ -247,8 +250,8 @@ class Storage {
247250
/// launch, where Storage was initialized while UserDefaults was encrypted and all values were
248251
/// cached as their defaults.
249252
///
250-
/// `migrationStep` is intentionally excluded: viewDidLoad writes it to 6 during the BFU
251-
/// launch; if we reloaded it and the flush had somehow not landed yet, migrations would re-run.
253+
/// `migrationStep` is intentionally excluded: viewDidLoad writes it to the latest step during
254+
/// the BFU launch; if we reloaded it and the flush had somehow not landed yet, migrations would re-run.
252255
///
253256
/// SecureStorageValue properties (maxBolus, maxCarbs, maxProtein, maxFat, bolusIncrement) are
254257
/// not covered here — SecureStorageValue does not implement reload() and Keychain has the same

LoopFollow/ViewControllers/MainViewController.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,12 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
10301030
// Capture before migrations run: true for existing users, false for fresh installs.
10311031
let isExistingUser = Storage.shared.migrationStep.exists
10321032

1033+
// When adding a new migration step below:
1034+
// 1. Bump the `migrationStep` defaultValue in Storage.swift to the new latest step
1035+
// number so fresh installs skip every migration.
1036+
// 2. Update any other StorageValue defaults in Storage.swift that this new step
1037+
// mutates, so a fresh install ends up in the same state as a migrated user.
1038+
10331039
// Step 1: Released in v3.0.0 (2025-07-07). Can be removed after 2026-07-07.
10341040
if Storage.shared.migrationStep.value < 1 {
10351041
Storage.shared.migrateStep1()

0 commit comments

Comments
 (0)