Skip to content

Commit 903c32e

Browse files
committed
Merge upstream dev 6.1.0 into watch-app
Brings in all changes from loopandlearn/LoopFollow dev up to 6.1.0. Resolved conflicts by taking upstream throughout, except LogManager where both the watch and telemetry log categories are kept. Key changes from upstream: - Add iOS 17.2+ push-to-start for Live Activity renewal (loopandlearn#622) - Fix LA restart classification, foreground race, troubleshooting logs (loopandlearn#615) - Redact secrets from log output (loopandlearn#623) - Add anonymous telemetry (loopandlearn#626) - Add units selection (loopandlearn#558) - Fix stats inclusive date range (loopandlearn#629) - Deduplicate Nightscout treatment entries by id (loopandlearn#569) - Fix alarm sound session activation failures in background (loopandlearn#596) - Recognize Atlas DASH pod in Omnipod heartbeat scan (loopandlearn#633) - Default migrationStep to latest on fresh installs (loopandlearn#631) - Update to fastlane 2.233.1 (loopandlearn#632) https://claude.ai/code/session_01VK2furpEaEmysQvEd1h77f
2 parents 12c2ab6 + 0d91b95 commit 903c32e

53 files changed

Lines changed: 1752 additions & 362 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Config.xcconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
unique_id = ${DEVELOPMENT_TEAM}
77

88
//Version (DEFAULT)
9-
LOOP_FOLLOW_MARKETING_VERSION = 6.0.9
9+
LOOP_FOLLOW_MARKETING_VERSION = 6.1.0

Gemfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
source "https://rubygems.org"
2-
gem "fastlane", "2.232.2"
2+
gem "fastlane", "2.233.1"
3+
gem "json", ">=2.19.2"
4+
gem "addressable", ">=2.9.0"

Gemfile.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ GEM
7272
faraday_middleware (1.2.1)
7373
faraday (~> 1.0)
7474
fastimage (2.4.0)
75-
fastlane (2.232.2)
75+
fastlane (2.233.1)
7676
CFPropertyList (>= 2.3, < 4.0.0)
7777
abbrev (~> 0.1.2)
7878
addressable (>= 2.8, < 3.0.0)
@@ -92,7 +92,7 @@ GEM
9292
faraday-cookie_jar (~> 0.0.6)
9393
faraday_middleware (~> 1.0)
9494
fastimage (>= 2.1.0, < 3.0.0)
95-
fastlane-sirp (>= 1.0.0)
95+
fastlane-sirp (>= 1.1.0)
9696
gh_inspector (>= 1.1.2, < 2.0.0)
9797
google-apis-androidpublisher_v3 (~> 0.3)
9898
google-apis-playcustomapp_v1 (~> 0.1)
@@ -122,8 +122,7 @@ GEM
122122
xcodeproj (>= 1.13.0, < 2.0.0)
123123
xcpretty (~> 0.4.1)
124124
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
125-
fastlane-sirp (1.0.0)
126-
sysrandom (~> 1.0)
125+
fastlane-sirp (1.1.0)
127126
gh_inspector (1.1.3)
128127
google-apis-androidpublisher_v3 (0.54.0)
129128
google-apis-core (>= 0.11.0, < 2.a)
@@ -203,7 +202,6 @@ GEM
203202
simctl (1.6.10)
204203
CFPropertyList
205204
naturally
206-
sysrandom (1.0.5)
207205
terminal-notifier (2.0.0)
208206
terminal-table (3.0.2)
209207
unicode-display_width (>= 1.1.1, < 3)
@@ -232,7 +230,9 @@ PLATFORMS
232230
ruby
233231

234232
DEPENDENCIES
235-
fastlane (= 2.232.2)
233+
addressable (>= 2.9.0)
234+
fastlane (= 2.233.1)
235+
json (>= 2.19.2)
236236

237237
BUNDLED WITH
238238
4.0.6

LoopFollow.xcodeproj/project.pbxproj

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@
7272
6589CC6F2E9E7D1600BB18FE /* AdvancedSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6589CC572E9E7D1600BB18FE /* AdvancedSettingsViewModel.swift */; };
7373
6589CC712E9E814F00BB18FE /* AlarmSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6589CC702E9E814F00BB18FE /* AlarmSelectionView.swift */; };
7474
6589CC752E9EAFB700BB18FE /* SettingsMigrationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6589CC742E9EAFB700BB18FE /* SettingsMigrationManager.swift */; };
75+
65A100012F5AA00000AA1001 /* UnitsSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65A100002F5AA00000AA1001 /* UnitsSettingsView.swift */; };
76+
65A100032F5AA00000AA1002 /* UnitsConfigurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65A100022F5AA00000AA1002 /* UnitsConfigurationView.swift */; };
7577
65E153C32E4BB69100693A4F /* URLTokenValidationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E153C22E4BB69100693A4F /* URLTokenValidationView.swift */; };
7678
65E8A2862E44B0300065037B /* VolumeButtonHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E8A2852E44B0300065037B /* VolumeButtonHandler.swift */; };
7779
66E3D12E66AA4534A144A54B /* BackgroundRefreshManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8CA8BE0B3D247408FE088B4 /* BackgroundRefreshManager.swift */; };
@@ -261,6 +263,7 @@
261263
DDD10F0B2C54192A00D76A8E /* TemporaryTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD10F0A2C54192A00D76A8E /* TemporaryTarget.swift */; };
262264
DDDB86F12DF7223C00AADDAC /* DeleteAlarmSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB86F02DF7223C00AADDAC /* DeleteAlarmSection.swift */; };
263265
DDDC01DD2E244B3100D9975C /* JWTManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDC01DC2E244B3100D9975C /* JWTManager.swift */; };
266+
A1A1A10002000000A0CFEED1 /* LogRedactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1A1A10002000000A0CFEED2 /* LogRedactor.swift */; };
264267
DDDC31CC2E13A7DF009EA0F3 /* AddAlarmSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDC31CB2E13A7DF009EA0F3 /* AddAlarmSheet.swift */; };
265268
DDDC31CE2E13A811009EA0F3 /* AlarmTile.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDC31CD2E13A811009EA0F3 /* AlarmTile.swift */; };
266269
DDDF6F492D479AF000884336 /* NoRemoteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDF6F482D479AEF00884336 /* NoRemoteView.swift */; };
@@ -302,6 +305,7 @@
302305
FC1BDD3224A2585C001B652C /* DataStructs.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC1BDD2E24A232A3001B652C /* DataStructs.swift */; };
303306
FC3AE7B5249E8E0E00AAE1E0 /* LoopFollow.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = FC3AE7B3249E8E0E00AAE1E0 /* LoopFollow.xcdatamodeld */; };
304307
FC3CAB022493B6220068A152 /* BackgroundTaskAudio.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC688592489554800A0279D /* BackgroundTaskAudio.swift */; };
308+
A1A1A10001000000A0CFEED1 /* APNsCredentialValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1A1A10001000000A0CFEED2 /* APNsCredentialValidator.swift */; };
305309
FC5A5C3D2497B229009C550E /* Config.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = FC5A5C3C2497B229009C550E /* Config.xcconfig */; };
306310
FC7CE518248ABE37001F83B8 /* Siri_Alert_Calibration_Needed.caf in Resources */ = {isa = PBXBuildFile; fileRef = FC7CE4A9248ABE2B001F83B8 /* Siri_Alert_Calibration_Needed.caf */; };
307311
FC7CE519248ABE37001F83B8 /* Rise_And_Shine.caf in Resources */ = {isa = PBXBuildFile; fileRef = FC7CE4AA248ABE2B001F83B8 /* Rise_And_Shine.caf */; };
@@ -434,6 +438,7 @@
434438
FCC6886B24898FD800A0279D /* ObservationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC6886A24898FD800A0279D /* ObservationToken.swift */; };
435439
FCC6886D2489909D00A0279D /* AnyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC6886C2489909D00A0279D /* AnyConvertible.swift */; };
436440
FCC6886F2489A53800A0279D /* AppConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC6886E2489A53800A0279D /* AppConstants.swift */; };
441+
9C7FB98C98BE4FF98F4815EE /* Telemetry.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDFBE69CEF18416D84959974 /* Telemetry.swift */; };
437442
FCD2A27D24C9D044009F7B7B /* Globals.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCD2A27C24C9D044009F7B7B /* Globals.swift */; };
438443
FCE537BC249A4D7D00F80BF8 /* carbBolusArrays.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE537BB249A4D7D00F80BF8 /* carbBolusArrays.swift */; };
439444
FCEF87AC24A141A700AE6FA0 /* Localizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEF87AA24A1417900AE6FA0 /* Localizer.swift */; };
@@ -548,6 +553,8 @@
548553
6589CC602E9E7D1600BB18FE /* TabCustomizationModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabCustomizationModal.swift; sourceTree = "<group>"; };
549554
6589CC702E9E814F00BB18FE /* AlarmSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlarmSelectionView.swift; sourceTree = "<group>"; };
550555
6589CC742E9EAFB700BB18FE /* SettingsMigrationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsMigrationManager.swift; sourceTree = "<group>"; };
556+
65A100002F5AA00000AA1001 /* UnitsSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitsSettingsView.swift; sourceTree = "<group>"; };
557+
65A100022F5AA00000AA1002 /* UnitsConfigurationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitsConfigurationView.swift; sourceTree = "<group>"; };
551558
65E153C22E4BB69100693A4F /* URLTokenValidationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLTokenValidationView.swift; sourceTree = "<group>"; };
552559
65E8A2852E44B0300065037B /* VolumeButtonHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VolumeButtonHandler.swift; sourceTree = "<group>"; };
553560
A7D55B42A22051DAD69E89D0 /* Pods_LoopFollow.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LoopFollow.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -740,6 +747,7 @@
740747
DDD10F0A2C54192A00D76A8E /* TemporaryTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemporaryTarget.swift; sourceTree = "<group>"; };
741748
DDDB86F02DF7223C00AADDAC /* DeleteAlarmSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteAlarmSection.swift; sourceTree = "<group>"; };
742749
DDDC01DC2E244B3100D9975C /* JWTManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JWTManager.swift; sourceTree = "<group>"; };
750+
A1A1A10002000000A0CFEED2 /* LogRedactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogRedactor.swift; sourceTree = "<group>"; };
743751
DDDC31CB2E13A7DF009EA0F3 /* AddAlarmSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAlarmSheet.swift; sourceTree = "<group>"; };
744752
DDDC31CD2E13A811009EA0F3 /* AlarmTile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlarmTile.swift; sourceTree = "<group>"; };
745753
DDDF6F482D479AEF00884336 /* NoRemoteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoRemoteView.swift; sourceTree = "<group>"; };
@@ -909,13 +917,15 @@
909917
FCA2DDE52501095000254A8C /* Timers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timers.swift; sourceTree = "<group>"; };
910918
FCC0FAC124922A22003E610E /* DictionaryKeyPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryKeyPath.swift; sourceTree = "<group>"; };
911919
FCC688592489554800A0279D /* BackgroundTaskAudio.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundTaskAudio.swift; sourceTree = "<group>"; };
920+
A1A1A10001000000A0CFEED2 /* APNsCredentialValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APNsCredentialValidator.swift; sourceTree = "<group>"; };
912921
FCC6885B2489559400A0279D /* blank.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = blank.wav; sourceTree = "<group>"; };
913922
FCC6885D24896A6C00A0279D /* silence.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = silence.mp3; sourceTree = "<group>"; };
914923
FCC6886624898F8000A0279D /* UserDefaultsValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsValue.swift; sourceTree = "<group>"; };
915924
FCC6886824898FB100A0279D /* UserDefaultsValueGroups.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsValueGroups.swift; sourceTree = "<group>"; };
916925
FCC6886A24898FD800A0279D /* ObservationToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservationToken.swift; sourceTree = "<group>"; };
917926
FCC6886C2489909D00A0279D /* AnyConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyConvertible.swift; sourceTree = "<group>"; };
918927
FCC6886E2489A53800A0279D /* AppConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppConstants.swift; sourceTree = "<group>"; };
928+
BDFBE69CEF18416D84959974 /* Telemetry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Telemetry.swift; sourceTree = "<group>"; };
919929
FCC688702489A57C00A0279D /* Loop Follow.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Loop Follow.entitlements"; sourceTree = "<group>"; };
920930
FCD2A27C24C9D044009F7B7B /* Globals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Globals.swift; sourceTree = "<group>"; };
921931
FCE537BB249A4D7D00F80BF8 /* carbBolusArrays.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = carbBolusArrays.swift; sourceTree = "<group>"; };
@@ -1031,6 +1041,8 @@
10311041
6589CC5E2E9E7D1600BB18FE /* GraphSettingsView.swift */,
10321042
657F98172F043D8100F732BD /* HomeContentView.swift */,
10331043
6589CC5F2E9E7D1600BB18FE /* SettingsMenuView.swift */,
1044+
65A100002F5AA00000AA1001 /* UnitsSettingsView.swift */,
1045+
65A100022F5AA00000AA1002 /* UnitsConfigurationView.swift */,
10341046
6589CC602E9E7D1600BB18FE /* TabCustomizationModal.swift */,
10351047
);
10361048
path = Settings;
@@ -1753,9 +1765,11 @@
17531765
DD7B0D432D730A320063DCB6 /* CycleHelper.swift */,
17541766
DDF6999C2C5AAA4C0058A8D9 /* Views */,
17551767
FCC6886E2489A53800A0279D /* AppConstants.swift */,
1768+
BDFBE69CEF18416D84959974 /* Telemetry.swift */,
17561769
FCC6886A24898FD800A0279D /* ObservationToken.swift */,
17571770
FCC6886C2489909D00A0279D /* AnyConvertible.swift */,
17581771
FCC688592489554800A0279D /* BackgroundTaskAudio.swift */,
1772+
A1A1A10001000000A0CFEED2 /* APNsCredentialValidator.swift */,
17591773
A8CA8BE0B3D247408FE088B4 /* BackgroundRefreshManager.swift */,
17601774
FCFEEC9F2488157B00402A7F /* Chart.swift */,
17611775
FCC0FAC124922A22003E610E /* DictionaryKeyPath.swift */,
@@ -1774,6 +1788,7 @@
17741788
DDF699952C5582290058A8D9 /* TextFieldWithToolBar.swift */,
17751789
DDC7E5372DBD887400EB1127 /* isOnPhoneCall.swift */,
17761790
DDDC01DC2E244B3100D9975C /* JWTManager.swift */,
1791+
A1A1A10002000000A0CFEED2 /* LogRedactor.swift */,
17771792
6541341B2E1DC28000BDBE08 /* DateExtensions.swift */,
17781793
);
17791794
path = Helpers;
@@ -2272,6 +2287,7 @@
22722287
DD0650ED2DCE9371004D3B41 /* HighBgAlarmEditor.swift in Sources */,
22732288
DD7F4C172DD63FA700D449E9 /* RecBolusCondition.swift in Sources */,
22742289
FCC6886F2489A53800A0279D /* AppConstants.swift in Sources */,
2290+
9C7FB98C98BE4FF98F4815EE /* Telemetry.swift in Sources */,
22752291
DDE75D2D2DE71401007C1FC1 /* TogglableSecureInput.swift in Sources */,
22762292
DD7E19842ACDA50C00DBD158 /* Overrides.swift in Sources */,
22772293
DD0B9D562DE1EC8A0090C337 /* AlarmType+Snooze.swift in Sources */,
@@ -2377,6 +2393,8 @@
23772393
6589CC6C2E9E7D1600BB18FE /* GraphSettingsView.swift in Sources */,
23782394
6589CC6D2E9E7D1600BB18FE /* CalendarSettingsView.swift in Sources */,
23792395
6589CC6E2E9E7D1600BB18FE /* SettingsMenuView.swift in Sources */,
2396+
65A100012F5AA00000AA1001 /* UnitsSettingsView.swift in Sources */,
2397+
65A100032F5AA00000AA1002 /* UnitsConfigurationView.swift in Sources */,
23802398
657F98182F043D8100F732BD /* HomeContentView.swift in Sources */,
23812399
6589CC6F2E9E7D1600BB18FE /* AdvancedSettingsViewModel.swift in Sources */,
23822400
DD493ADF2ACF22BB009A6922 /* SAge.swift in Sources */,
@@ -2414,6 +2432,7 @@
24142432
DD4A407E2E6AFEE6007B318B /* AuthService.swift in Sources */,
24152433
654134182E1DC09700BDBE08 /* OverridePresetsView.swift in Sources */,
24162434
DDDC01DD2E244B3100D9975C /* JWTManager.swift in Sources */,
2435+
A1A1A10002000000A0CFEED1 /* LogRedactor.swift in Sources */,
24172436
DDD10F072C529DE800D76A8E /* Observable.swift in Sources */,
24182437
DDFF3D852D14279B00BF9D9E /* BackgroundRefreshSettingsView.swift in Sources */,
24192438
DDCF9A882D85FD33004DF4DD /* AlarmData.swift in Sources */,
@@ -2499,6 +2518,7 @@
24992518
DD493ADD2ACF21E0009A6922 /* Basals.swift in Sources */,
25002519
FC16A98124996C07003D6245 /* DateTime.swift in Sources */,
25012520
FC3CAB022493B6220068A152 /* BackgroundTaskAudio.swift in Sources */,
2521+
A1A1A10001000000A0CFEED1 /* APNsCredentialValidator.swift in Sources */,
25022522
DDCC3A582DDC9655006F1C10 /* MissedBolusAlarmEditor.swift in Sources */,
25032523
DDEF50402D479B8A00884336 /* LoopAPNSService.swift in Sources */,
25042524
DD485F142E454B2600CE8CBF /* SecureMessenger.swift in Sources */,

LoopFollow/Application/AppDelegate.swift

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,27 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
5050

5151
BackgroundRefreshManager.shared.register()
5252

53-
// Detect Before-First-Unlock launch. isProtectedDataAvailable returns false
54-
// for ANY locked-screen background launch, not only post-reboot. Standard
55-
// UserDefaults use NSFileProtectionCompleteUntilFirstUserAuthentication —
56-
// they stay readable after the first unlock even when the screen is locked.
57-
// True BFU (boot before first unlock) is the only case where UserDefaults
58-
// is actually inaccessible; in that state every StorageValue reads as its
59-
// default — including migrationStep, which is always ≥ 1 for existing users.
60-
// Guard against false positives by checking that migrationStep is still 0
61-
// (its default), meaning the real value couldn't be read from disk.
62-
let protectedDataUnavailable = !UIApplication.shared.isProtectedDataAvailable
63-
let bfu = protectedDataUnavailable && Storage.shared.migrationStep.value == 0
53+
// Telemetry: record this cold launch (used by the rolling
54+
// coldLaunches7d signal). If the running build's SHA differs from
55+
// the one we last sent for, fire an immediate ping — the scheduler
56+
// alone can't notice an app update. Otherwise let the 24h scheduler
57+
// handle cadence: its first run is lastSentAt + 24h, so a relaunch
58+
// a few hours after the previous send simply waits out the
59+
// remainder. See Helpers/Telemetry.swift.
60+
TelemetryClient.shared.recordColdLaunch()
61+
Task.detached {
62+
if TelemetryClient.shared.buildShaChangedSinceLastSend() {
63+
await TelemetryClient.shared.maybeSend()
64+
}
65+
TelemetryClient.shared.scheduleRecurring()
66+
}
67+
68+
// Detect Before-First-Unlock launch. If protected data is unavailable here,
69+
// StorageValues were cached from encrypted UserDefaults and need a reload
70+
// on the first foreground after the user unlocks.
71+
let bfu = !UIApplication.shared.isProtectedDataAvailable
6472
Storage.shared.needsBFUReload = bfu
65-
LogManager.shared.log(category: .general, message: "BFU check: isProtectedDataAvailable=\(!protectedDataUnavailable), migrationStep=\(Storage.shared.migrationStep.value), needsBFUReload=\(bfu)")
73+
LogManager.shared.log(category: .general, message: "BFU check: isProtectedDataAvailable=\(!bfu), needsBFUReload=\(bfu)")
6674

6775
return true
6876
}
@@ -81,7 +89,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
8189

8290
Observable.shared.loopFollowDeviceToken.value = tokenString
8391

84-
LogManager.shared.log(category: .apns, message: "Successfully registered for remote notifications with token: \(tokenString)")
92+
LogManager.shared.log(category: .apns, message: "Successfully registered for remote notifications with token: \(LogRedactor.tail(tokenString))")
8593
}
8694

8795
/// Called when failed to register for remote notifications
@@ -91,7 +99,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
9199

92100
/// Called when a remote notification is received
93101
func application(_: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
94-
LogManager.shared.log(category: .apns, message: "Received remote notification: \(userInfo)")
102+
let userInfoKeys = userInfo.keys.compactMap { $0 as? String }.sorted()
103+
LogManager.shared.log(category: .apns, message: "Received remote notification: keys=\(userInfoKeys)")
95104

96105
// Check if this is a response notification from Loop or Trio
97106
if let aps = userInfo["aps"] as? [String: Any] {
@@ -229,7 +238,8 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
229238
{
230239
// Log the notification
231240
let userInfo = notification.request.content.userInfo
232-
LogManager.shared.log(category: .general, message: "Will present notification: \(userInfo)")
241+
let userInfoKeys = userInfo.keys.compactMap { $0 as? String }.sorted()
242+
LogManager.shared.log(category: .general, message: "Will present notification: keys=\(userInfoKeys)")
233243

234244
// Show the notification even when app is in foreground
235245
completionHandler([.banner, .sound, .badge])

0 commit comments

Comments
 (0)