From 81827e21a454e2881518ad24cf5199dd186de15e Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 12 Oct 2026 01:08:51 -0500 Subject: [PATCH] Clean up compiler warnings that don't involve concurrency - Live Activity: an activity preset fell through @unknown default and showed an empty title. It now shows its preset's name and symbol, and the switch is exhaustive so a new context can't be missed again. - Throwing tasks whose errors were dropped now log them. Retracting the unsafe-notification-permissions alert dismisses the in-app alert even if recording the retraction fails, and the insulin delivery log opens a dose's details even if its dosing decision can't be found. - Mark conformances of types and protocols from other modules @retroactive. - Move off deprecated APIs: onChange(of:perform:), traitCollectionDidChange (now registerForTraitChanges with the traits that affect colours), HKCategoryValueSleepAnalysis.asleep, WKExtension.applicationWillResignActiveNotification. - Remove unused values and the tuple-pattern warning. --- .../Extensions/TextFieldTableViewCell.swift | 2 +- Loop/Extensions/UIDevice+Loop.swift | 2 +- Loop/Extensions/UITableViewCell.swift | 2 +- Loop/Extensions/UserNotifications+Loop.swift | 8 ++--- Loop/Managers/Alerts/AlertManager.swift | 12 +++++-- .../Alerts/InAppModalAlertScheduler.swift | 12 ++++--- Loop/Managers/DeviceDataManager.swift | 8 ++--- .../Live Activity/LiveActivityManager.swift | 32 +++++++++++-------- .../MealDetectionManager.swift | 2 -- Loop/Managers/RemoteDataServicesManager.swift | 2 +- Loop/Managers/SleepStore.swift | 2 +- Loop/Models/GlucoseEffectVelocity.swift | 2 +- .../CarbAbsorptionViewController.swift | 1 - .../StatusTableViewController.swift | 7 ++-- .../FavoriteFoodInsightsViewModel.swift | 2 +- Loop/Views/AlertManagementView.swift | 2 +- Loop/Views/BolusProgressTableViewCell.swift | 10 +++--- Loop/Views/CarbEntryView.swift | 2 +- .../Favorite Foods/FavoriteFoodsView.swift | 2 +- .../IconTitleSubtitleTableViewCell.swift | 9 ++---- Loop/Views/LiveActivityManagementView.swift | 16 +++++----- Loop/Views/ManualGlucoseEntryRow.swift | 8 ++--- Loop/Views/TitleSubtitleTableViewCell.swift | 9 ++---- ...henticationTableViewCell+NibLoadable.swift | 2 +- .../Carb Entry & Bolus/CarbAndBolusFlow.swift | 2 +- .../Views/PresetActivateCrownConfirm.swift | 2 +- 26 files changed, 82 insertions(+), 78 deletions(-) diff --git a/Common/Extensions/TextFieldTableViewCell.swift b/Common/Extensions/TextFieldTableViewCell.swift index 82c5867cc3..4a694cff0f 100644 --- a/Common/Extensions/TextFieldTableViewCell.swift +++ b/Common/Extensions/TextFieldTableViewCell.swift @@ -9,4 +9,4 @@ import LoopKitUI import LoopUI -extension TextFieldTableViewCell: NibLoadable { } +extension TextFieldTableViewCell: @retroactive NibLoadable { } diff --git a/Loop/Extensions/UIDevice+Loop.swift b/Loop/Extensions/UIDevice+Loop.swift index a9655723ed..c5878ef0f6 100644 --- a/Loop/Extensions/UIDevice+Loop.swift +++ b/Loop/Extensions/UIDevice+Loop.swift @@ -74,7 +74,7 @@ extension UIDevice.BatteryState { } } -extension UIDevice.BatteryState: CustomStringConvertible { +extension UIDevice.BatteryState: @retroactive CustomStringConvertible { public var description: String { switch self { case .unknown: diff --git a/Loop/Extensions/UITableViewCell.swift b/Loop/Extensions/UITableViewCell.swift index 5b9ac0ff2f..ceff2686c4 100644 --- a/Loop/Extensions/UITableViewCell.swift +++ b/Loop/Extensions/UITableViewCell.swift @@ -10,4 +10,4 @@ import UIKit import LoopCore -extension UITableViewCell: IdentifiableClass { } +extension UITableViewCell: @retroactive IdentifiableClass { } diff --git a/Loop/Extensions/UserNotifications+Loop.swift b/Loop/Extensions/UserNotifications+Loop.swift index dd5eec862d..727f45c417 100644 --- a/Loop/Extensions/UserNotifications+Loop.swift +++ b/Loop/Extensions/UserNotifications+Loop.swift @@ -31,7 +31,7 @@ extension UNUserNotificationCenter { } } -extension UNAuthorizationStatus: CustomStringConvertible { +extension UNAuthorizationStatus: @retroactive CustomStringConvertible { public var description: String { switch self { case .notDetermined: @@ -50,7 +50,7 @@ extension UNAuthorizationStatus: CustomStringConvertible { } } -extension UNShowPreviewsSetting: CustomStringConvertible { +extension UNShowPreviewsSetting: @retroactive CustomStringConvertible { public var description: String { switch self { case .always: @@ -65,7 +65,7 @@ extension UNShowPreviewsSetting: CustomStringConvertible { } } -extension UNNotificationSetting: CustomStringConvertible { +extension UNNotificationSetting: @retroactive CustomStringConvertible { public var description: String { switch self { case .notSupported: @@ -80,7 +80,7 @@ extension UNNotificationSetting: CustomStringConvertible { } } -extension UNAlertStyle: CustomStringConvertible { +extension UNAlertStyle: @retroactive CustomStringConvertible { public var description: String { switch self { case .none: diff --git a/Loop/Managers/Alerts/AlertManager.swift b/Loop/Managers/Alerts/AlertManager.swift index a5a185c356..e08c6d3a3d 100644 --- a/Loop/Managers/Alerts/AlertManager.swift +++ b/Loop/Managers/Alerts/AlertManager.swift @@ -766,7 +766,11 @@ extension AlertManager: AlertPermissionsCheckerDelegate { retractionHandler: { alert in // need to dismiss the in-app alert outside of the alert system Task { - try await self.recordRetractedAlert(alert, at: Date()) + do { + try await self.recordRetractedAlert(alert, at: Date()) + } catch { + self.log.error("Error recording retracted alert: %{public}@", String(describing: error)) + } await self.dismissUnsafeNotificationPermissionsInAppAlert() } } @@ -800,7 +804,11 @@ extension AlertManager: AlertPermissionsCheckerDelegate { let alertController = AlertPermissionsChecker.constructUnsafeNotificationPermissionsInAppAlert(alert: alert) { [weak self] alert in UserDefaults.standard.hasIssuedNotificationPermissionsAlert = false Task { - try await self?.acknowledgeAlert(identifier: alert.alertIdentifier) + do { + try await self?.acknowledgeAlert(identifier: alert.alertIdentifier) + } catch { + self?.log.error("Error acknowledging alert: %{public}@", String(describing: error)) + } } } diff --git a/Loop/Managers/Alerts/InAppModalAlertScheduler.swift b/Loop/Managers/Alerts/InAppModalAlertScheduler.swift index a762f3c60e..f13e12c718 100644 --- a/Loop/Managers/Alerts/InAppModalAlertScheduler.swift +++ b/Loop/Managers/Alerts/InAppModalAlertScheduler.swift @@ -113,10 +113,14 @@ extension InAppModalAlertScheduler { // the completion is called after the alert is acknowledged self?.clearPresentedAlert(identifier: alert.identifier) Task { - if action.identifier == "acknowledge" { - try await self?.alertManagerResponder?.acknowledgeAlert(identifier: alert.identifier) - } else { - try await self?.alertManagerResponder?.userDidSelectAction(alertIdentifier: alert.identifier, actionIdentifier: action.identifier) + do { + if action.identifier == "acknowledge" { + try await self?.alertManagerResponder?.acknowledgeAlert(identifier: alert.identifier) + } else { + try await self?.alertManagerResponder?.userDidSelectAction(alertIdentifier: alert.identifier, actionIdentifier: action.identifier) + } + } catch { + self?.log.error("Error responding to alert action: %{public}@", String(describing: error)) } } } diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index d32c2a2765..142a1092ff 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -1292,9 +1292,7 @@ extension DeviceDataManager { } func deleteTestingCarbData(before: Date = Date()) async throws { - guard let testingCGMManager = cgmManager as? TestingCGMManager, - let testingPumpManager = pumpManager as? TestingPumpManager - else { + guard cgmManager is TestingCGMManager, pumpManager is TestingPumpManager else { return } @@ -1302,9 +1300,7 @@ extension DeviceDataManager { } func deleteTestingAlertData() async throws { - guard let testingCGMManager = cgmManager as? TestingCGMManager, - let testingPumpManager = pumpManager as? TestingPumpManager - else { + guard cgmManager is TestingCGMManager, pumpManager is TestingPumpManager else { return } diff --git a/Loop/Managers/Live Activity/LiveActivityManager.swift b/Loop/Managers/Live Activity/LiveActivityManager.swift index a9db6b7e3e..2e58e1d707 100644 --- a/Loop/Managers/Live Activity/LiveActivityManager.swift +++ b/Loop/Managers/Live Activity/LiveActivityManager.swift @@ -562,24 +562,28 @@ extension TemporaryScheduleOverride { func liveActivityTitleAndSymbol() -> (title: String, systemSymbolName: String?) { switch context { case .preset(let preset): - guard let symbol = preset.symbol else { - return (preset.name, nil) - } - switch symbol.symbolType { - case .emoji: - return ("\(symbol.value) \(preset.name)", nil) - case .systemImage: - return (preset.name, symbol.value) - case .image: - // Asset-image symbols can't be loaded from the widget bundle; render name only. - return (preset.name, nil) - } + return Self.titleAndSymbol(for: preset) + case .activity(let activity): + return Self.titleAndSymbol(for: activity.preset) case .custom: return (NSLocalizedString("Custom preset", comment: "The title of the cell indicating a generic custom preset is enabled"), nil) case .preMeal: return (NSLocalizedString("Pre-meal Preset", comment: "Status row title for premeal override enabled"), "fork.knife") - @unknown default: - return ("", nil) + } + } + + private static func titleAndSymbol(for preset: TemporaryPreset) -> (title: String, systemSymbolName: String?) { + guard let symbol = preset.symbol else { + return (preset.name, nil) + } + switch symbol.symbolType { + case .emoji: + return ("\(symbol.value) \(preset.name)", nil) + case .systemImage: + return (preset.name, symbol.value) + case .image: + // Asset-image symbols can't be loaded from the widget bundle; render name only. + return (preset.name, nil) } } } diff --git a/Loop/Managers/Missed Meal Detection/MealDetectionManager.swift b/Loop/Managers/Missed Meal Detection/MealDetectionManager.swift index 979009f92b..32b2dd37ce 100644 --- a/Loop/Managers/Missed Meal Detection/MealDetectionManager.swift +++ b/Loop/Managers/Missed Meal Detection/MealDetectionManager.swift @@ -83,8 +83,6 @@ class MealDetectionManager { } let date = test_currentDate ?? Date() - let samplesStart = date.addingTimeInterval(-MissedMealSettings.maxRecency) - guard let sensitivitySchedule = settingsProvider.insulinSensitivityScheduleApplyingOverrideHistory, let carbRatioSchedule = settingsProvider.carbRatioSchedule, let maxBolus = settingsProvider.maximumBolus else diff --git a/Loop/Managers/RemoteDataServicesManager.swift b/Loop/Managers/RemoteDataServicesManager.swift index 11712704e7..b28583fb66 100644 --- a/Loop/Managers/RemoteDataServicesManager.swift +++ b/Loop/Managers/RemoteDataServicesManager.swift @@ -271,7 +271,7 @@ extension RemoteDataServicesManager { case .failure(let error): self.log.error("Error querying alert data: %{public}@", String(describing: error)) semaphore.signal() - case .success(let queryAnchor, let data): + case .success((let queryAnchor, let data)): Task { do { try await remoteDataService.uploadAlertData(data) diff --git a/Loop/Managers/SleepStore.swift b/Loop/Managers/SleepStore.swift index 723a4f6496..4865fc98dc 100644 --- a/Loop/Managers/SleepStore.swift +++ b/Loop/Managers/SleepStore.swift @@ -47,7 +47,7 @@ class SleepStore { // if there were no .inBed samples, check if there are any .asleep samples that could be used to estimate bedtime let asleepPredicate = HKQuery.predicateForCategorySamples( with: .equalTo, - value: HKCategoryValueSleepAnalysis.asleep.rawValue + value: HKCategoryValueSleepAnalysis.asleepUnspecified.rawValue ) self.getAverageSleepStartTime(matching: asleepPredicate, sampleLimit: sampleLimit, completion) default: diff --git a/Loop/Models/GlucoseEffectVelocity.swift b/Loop/Models/GlucoseEffectVelocity.swift index 4a9ab40796..6a731611bf 100644 --- a/Loop/Models/GlucoseEffectVelocity.swift +++ b/Loop/Models/GlucoseEffectVelocity.swift @@ -9,7 +9,7 @@ import LoopKit import LoopAlgorithm -extension GlucoseEffectVelocity: RawRepresentable { +extension GlucoseEffectVelocity: @retroactive RawRepresentable { public typealias RawValue = [String: Any] static let unit = LoopUnit.milligramsPerDeciliterPerMinute diff --git a/Loop/View Controllers/CarbAbsorptionViewController.swift b/Loop/View Controllers/CarbAbsorptionViewController.swift index cd4f44e2b0..3effa663a9 100644 --- a/Loop/View Controllers/CarbAbsorptionViewController.swift +++ b/Loop/View Controllers/CarbAbsorptionViewController.swift @@ -291,7 +291,6 @@ final class CarbAbsorptionViewController: LoopChartsTableViewController, Identif return cell case .entries: - let unit = LoopUnit.gram let cell = tableView.dequeueReusableCell(withIdentifier: CarbEntryTableViewCell.className, for: indexPath) as! CarbEntryTableViewCell cell.accessibilityIdentifier = "cell_CarbEntry" diff --git a/Loop/View Controllers/StatusTableViewController.swift b/Loop/View Controllers/StatusTableViewController.swift index 91b1faa4b1..f41af52d7c 100644 --- a/Loop/View Controllers/StatusTableViewController.swift +++ b/Loop/View Controllers/StatusTableViewController.swift @@ -499,7 +499,6 @@ final class StatusTableViewController: LoopChartsTableViewController { var cobValues: [CarbValue]? var carbsOnBoard: LoopQuantity? let startDate = charts.startDate - let basalDeliveryState = self.basalDeliveryState let automaticDosingEnabled = settingsManager.dosingEnabled let state = await loopManager.algorithmDisplayState @@ -1363,7 +1362,11 @@ final class StatusTableViewController: LoopChartsTableViewController { Task { var dosingDecision: StoredDosingDecision? if let decisionId = doseEntry.decisionId { - dosingDecision = try await self.loopManager.dosingDecisionStore.findDosingDecisionsById(decisionId) + do { + dosingDecision = try await self.loopManager.dosingDecisionStore.findDosingDecisionsById(decisionId) + } catch { + self.log.error("Error finding dosing decision: %{public}@", String(describing: error)) + } } let viewController = CommandResponseViewController(command: { (completionHandler) -> String in diff --git a/Loop/View Models/FavoriteFoodInsightsViewModel.swift b/Loop/View Models/FavoriteFoodInsightsViewModel.swift index 502b3e0915..25a6599d7b 100644 --- a/Loop/View Models/FavoriteFoodInsightsViewModel.swift +++ b/Loop/View Models/FavoriteFoodInsightsViewModel.swift @@ -132,7 +132,7 @@ class FavoriteFoodInsightsViewModel: ObservableObject { Task { @MainActor in do { if let historicalChartsData = try await delegate?.getHistoricalChartsData(start: dateInterval.start, end: dateInterval.end) { - var carbEntriesWithCorrectedFavoriteFoods = historicalChartsData.carbEntries.map({ historicalCarbEntry in + let carbEntriesWithCorrectedFavoriteFoods = historicalChartsData.carbEntries.map({ historicalCarbEntry in // only show a favorite food icon in the glcuose-carb chart if carb entry is currently viewed favorite food StoredCarbEntry( startDate: historicalCarbEntry.startDate, diff --git a/Loop/Views/AlertManagementView.swift b/Loop/Views/AlertManagementView.swift index 4fce6bde7c..674ca39e28 100644 --- a/Loop/Views/AlertManagementView.swift +++ b/Loop/Views/AlertManagementView.swift @@ -162,7 +162,7 @@ struct AlertManagementView: View { ConfirmationSheet(resumeDate: resumeDate) } } - .onChange(of: durationWasSelection) { _ in + .onChange(of: durationWasSelection) { if durationWasSelection, let durationSelection, let durationSelectionString = formatter.string(from: durationSelection) { sheet = .confirmation(resumeDate: Date().addingTimeInterval(durationSelection)) formattedSelectedDuration.wrappedValue = durationSelectionString diff --git a/Loop/Views/BolusProgressTableViewCell.swift b/Loop/Views/BolusProgressTableViewCell.swift index 0ee4aeb790..f8d801da55 100644 --- a/Loop/Views/BolusProgressTableViewCell.swift +++ b/Loop/Views/BolusProgressTableViewCell.swift @@ -73,6 +73,10 @@ public class BolusProgressTableViewCell: UITableViewCell { (progressLabel.superview as? UIStackView)?.addArrangedSubview(infoButton) + registerForTraitChanges(UITraitCollection.systemTraitsAffectingColorAppearance) { (cell: Self, _: UITraitCollection) in + cell.updateColors() + } + paddedView.layer.masksToBounds = true paddedView.layer.cornerRadius = 10 paddedView.layer.borderWidth = 1 @@ -86,12 +90,6 @@ public class BolusProgressTableViewCell: UITableViewCell { updateColors() } - public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - - updateColors() - } - private func updateColors() { progressIndicator.startColor = tintColor progressIndicator.endColor = tintColor diff --git a/Loop/Views/CarbEntryView.swift b/Loop/Views/CarbEntryView.swift index 4492102c9d..04118990ec 100644 --- a/Loop/Views/CarbEntryView.swift +++ b/Loop/Views/CarbEntryView.swift @@ -298,7 +298,7 @@ extension CarbEntryView { .padding(.horizontal) .background(CardBackground()) .padding(.horizontal) - .onChange(of: viewModel.selectedFavoriteFoodIndex, perform: collapseFavoriteFoodsRowIfNeeded(_:)) + .onChange(of: viewModel.selectedFavoriteFoodIndex) { _, newIndex in collapseFavoriteFoodsRowIfNeeded(newIndex) } } } diff --git a/Loop/Views/Favorite Foods/FavoriteFoodsView.swift b/Loop/Views/Favorite Foods/FavoriteFoodsView.swift index 17631d2b54..bdeb1dd62b 100644 --- a/Loop/Views/Favorite Foods/FavoriteFoodsView.swift +++ b/Loop/Views/Favorite Foods/FavoriteFoodsView.swift @@ -70,7 +70,7 @@ struct FavoriteFoodsView: View { .sheet(isPresented: $viewModel.isAddViewActive) { FavoriteFoodAddEditView(onSave: viewModel.onFoodSave(_:)) } - .onChange(of: editMode) { newValue in + .onChange(of: editMode) { _, newValue in if !newValue.isEditing { foodToConfirmDeleteId = nil } diff --git a/Loop/Views/IconTitleSubtitleTableViewCell.swift b/Loop/Views/IconTitleSubtitleTableViewCell.swift index 5ecc166614..788757a4f8 100644 --- a/Loop/Views/IconTitleSubtitleTableViewCell.swift +++ b/Loop/Views/IconTitleSubtitleTableViewCell.swift @@ -36,12 +36,9 @@ class IconTitleSubtitleTableViewCell: UITableViewCell { backgroundView?.layer.insertSublayer(gradient, at: 0) updateColors() - } - - public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - - updateColors() + registerForTraitChanges(UITraitCollection.systemTraitsAffectingColorAppearance) { (cell: Self, _: UITraitCollection) in + cell.updateColors() + } } private func updateColors() { diff --git a/Loop/Views/LiveActivityManagementView.swift b/Loop/Views/LiveActivityManagementView.swift index 84dba8590d..49c0c7bf4c 100644 --- a/Loop/Views/LiveActivityManagementView.swift +++ b/Loop/Views/LiveActivityManagementView.swift @@ -23,7 +23,7 @@ struct LiveActivityManagementView: View { List { Section(header: Text("Lock Screen / Dynamic Island / CarPlay")) { Toggle(NSLocalizedString("Enabled", comment: "Title for enable live activity toggle"), isOn: $viewModel.enabled) - .onChange(of: viewModel.enabled) { _ in + .onChange(of: viewModel.enabled) { self.isDirty = previousViewModel.enabled != viewModel.enabled } } @@ -49,7 +49,7 @@ struct LiveActivityManagementView: View { .labelsHidden() } ) - .onChange(of: viewModel.mode) { _ in + .onChange(of: viewModel.mode) { self.isDirty = previousViewModel.mode != viewModel.mode } } @@ -57,13 +57,13 @@ struct LiveActivityManagementView: View { Section(header: Text("Display Control Options")) { Toggle(NSLocalizedString("Display prediction in plot", comment: "Title for prediction line toggle"), isOn: $viewModel.addPredictiveLine) .transition(.move(edge: viewModel.mode == .large ? .top : .bottom)) - .onChange(of: viewModel.addPredictiveLine) { _ in + .onChange(of: viewModel.addPredictiveLine) { self.isDirty = previousViewModel.addPredictiveLine != viewModel.addPredictiveLine } Toggle(NSLocalizedString("Display colors for glucose", comment: "Title for glucose coloring"), isOn: $viewModel.useLimits) .transition(.move(edge: viewModel.mode == .large ? .top : .bottom)) - .onChange(of: viewModel.useLimits) { _ in + .onChange(of: viewModel.useLimits) { self.isDirty = previousViewModel.useLimits != viewModel.useLimits } @@ -71,23 +71,23 @@ struct LiveActivityManagementView: View { if self.displayGlucosePreference.unit == .millimolesPerLiter { TextInput(label: "Upper limit", value: $viewModel.upperLimitChartMmol) .transition(.move(edge: viewModel.useLimits ? .top : .bottom)) - .onChange(of: viewModel.upperLimitChartMmol) { _ in + .onChange(of: viewModel.upperLimitChartMmol) { self.isDirty = previousViewModel.upperLimitChartMmol != viewModel.upperLimitChartMmol } TextInput(label: "Lower limit", value: $viewModel.lowerLimitChartMmol) .transition(.move(edge: viewModel.useLimits ? .top : .bottom)) - .onChange(of: viewModel.lowerLimitChartMmol) { _ in + .onChange(of: viewModel.lowerLimitChartMmol) { self.isDirty = previousViewModel.lowerLimitChartMmol != viewModel.lowerLimitChartMmol } } else { TextInput(label: "Upper limit", value: $viewModel.upperLimitChartMg) .transition(.move(edge: viewModel.useLimits ? .top : .bottom)) - .onChange(of: viewModel.upperLimitChartMg) { _ in + .onChange(of: viewModel.upperLimitChartMg) { self.isDirty = previousViewModel.upperLimitChartMg != viewModel.upperLimitChartMg } TextInput(label: "Lower limit", value: $viewModel.lowerLimitChartMg) .transition(.move(edge: viewModel.useLimits ? .top : .bottom)) - .onChange(of: viewModel.lowerLimitChartMg) { _ in + .onChange(of: viewModel.lowerLimitChartMg) { self.isDirty = previousViewModel.lowerLimitChartMg != viewModel.lowerLimitChartMg } } diff --git a/Loop/Views/ManualGlucoseEntryRow.swift b/Loop/Views/ManualGlucoseEntryRow.swift index 30e569cec9..c3cda677fa 100644 --- a/Loop/Views/ManualGlucoseEntryRow.swift +++ b/Loop/Views/ManualGlucoseEntryRow.swift @@ -40,16 +40,16 @@ struct ManualGlucoseEntryRow: View { maxLength: 4, doneButtonColor: .loopAccent ) - .onChange(of: valueText, perform: { value in + .onChange(of: valueText) { if let manualGlucoseValue = displayGlucosePreference.formatter.numberFormatter.number(from: valueText)?.doubleValue { quantity = LoopQuantity(unit: displayGlucosePreference.unit, doubleValue: manualGlucoseValue) } else { quantity = nil } - }) - .onChange(of: displayGlucosePreference.unit, perform: { value in + } + .onChange(of: displayGlucosePreference.unit) { unitsChanged() - }) + } .accessibilityIdentifier("textField_FingerstickGlucose") Text(displayGlucosePreference.formatter.localizedUnitStringWithPlurality()) diff --git a/Loop/Views/TitleSubtitleTableViewCell.swift b/Loop/Views/TitleSubtitleTableViewCell.swift index ce1dbe815a..a576c1c1ea 100644 --- a/Loop/Views/TitleSubtitleTableViewCell.swift +++ b/Loop/Views/TitleSubtitleTableViewCell.swift @@ -34,12 +34,9 @@ class TitleSubtitleTableViewCell: UITableViewCell { backgroundView?.layer.insertSublayer(gradient, at: 0) updateColors() - } - - public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - - updateColors() + registerForTraitChanges(UITraitCollection.systemTraitsAffectingColorAppearance) { (cell: Self, _: UITraitCollection) in + cell.updateColors() + } } private func updateColors() { diff --git a/LoopUI/Extensions/AuthenticationTableViewCell+NibLoadable.swift b/LoopUI/Extensions/AuthenticationTableViewCell+NibLoadable.swift index aaa46dfe6b..621fb950d2 100644 --- a/LoopUI/Extensions/AuthenticationTableViewCell+NibLoadable.swift +++ b/LoopUI/Extensions/AuthenticationTableViewCell+NibLoadable.swift @@ -10,4 +10,4 @@ import LoopKitUI /// Allow AuthenticationTableViewCell to be loaded from nib -extension AuthenticationTableViewCell: NibLoadable { } +extension AuthenticationTableViewCell: @retroactive NibLoadable { } diff --git a/WatchApp Extension/Views/Carb Entry & Bolus/CarbAndBolusFlow.swift b/WatchApp Extension/Views/Carb Entry & Bolus/CarbAndBolusFlow.swift index e694105a06..6df4060370 100644 --- a/WatchApp Extension/Views/Carb Entry & Bolus/CarbAndBolusFlow.swift +++ b/WatchApp Extension/Views/Carb Entry & Bolus/CarbAndBolusFlow.swift @@ -99,7 +99,7 @@ struct CarbAndBolusFlow: View { activity.becomeCurrent() } - .onReceive(NotificationCenter.default.publisher(for: WKExtension.applicationWillResignActiveNotification)) { _ in + .onReceive(NotificationCenter.default.publisher(for: WKApplication.willResignActiveNotification)) { _ in dismiss() } } diff --git a/WatchApp Extension/Views/PresetActivateCrownConfirm.swift b/WatchApp Extension/Views/PresetActivateCrownConfirm.swift index 03f5ff55db..6451882506 100644 --- a/WatchApp Extension/Views/PresetActivateCrownConfirm.swift +++ b/WatchApp Extension/Views/PresetActivateCrownConfirm.swift @@ -64,7 +64,7 @@ struct PresetActivateCrownConfirm: View { // are being dismissed, treat the dismissal as an acknowledgement loopManager.pendingPresetReminder = nil Task { - try await loopManager.acknowledgeAlert(alertIdentifier: reminder.alertIdentifier, managerIdentifier: reminder.managerIdentifier) + try? await loopManager.acknowledgeAlert(alertIdentifier: reminder.alertIdentifier, managerIdentifier: reminder.managerIdentifier) } } }